Exemple #1
0
static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
  ARegion *ar = CTX_wm_region(C);
  uiBut *but = NULL;
  float color[4];
  bool gamma;

  RNA_float_get_array(op->ptr, "color", color);
  gamma = RNA_boolean_get(op->ptr, "gamma");

  /* find button under mouse, check if it has RNA color property and
   * if it does copy the data */
  but = ui_region_find_active_but(ar);

  if (but && but->type == UI_BTYPE_COLOR && but->rnaprop) {
    const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop);
    BLI_assert(color_len <= 4);

    /* keep alpha channel as-is */
    if (color_len == 4) {
      color[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3);
    }

    if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) {
      if (!gamma) {
        IMB_colormanagement_scene_linear_to_srgb_v3(color);
      }
      RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
      RNA_property_update(C, &but->rnapoin, but->rnaprop);
    }
    else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) {
      if (gamma) {
        IMB_colormanagement_srgb_to_scene_linear_v3(color);
      }
      RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color);
      RNA_property_update(C, &but->rnapoin, but->rnaprop);
    }
  }
  else {
    if (gamma) {
      srgb_to_linearrgb_v3_v3(color, color);
    }

    ED_imapaint_bucket_fill(C, color, op);
  }

  ED_region_tag_redraw(ar);

  return OPERATOR_FINISHED;
}
static void eyedropper_colorband_cancel(bContext *C, wmOperator *op)
{
	EyedropperColorband *eye = op->customdata;
	*eye->color_band = eye->init_color_band;
	RNA_property_update(C, &eye->ptr, eye->prop);
	eyedropper_colorband_exit(C, op);
}
Exemple #3
0
int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
{
	ID *newid = NULL;
	PointerRNA idptr;
	
	if (id) {
		/* if property isn't editable, we're going to have an extra block hanging around until we save */
		if (RNA_property_editable(ptr, prop)) {
			if (id_copy(id, &newid, 0) && newid) {
				/* copy animation actions too */
				BKE_copy_animdata_id_action(id);
				/* us is 1 by convention, but RNA_property_pointer_set
				   will also incremement it, so set it to zero */
				newid->us= 0;
				
				/* assign copy */
				RNA_id_pointer_create(newid, &idptr);
				RNA_property_pointer_set(ptr, prop, idptr);
				RNA_property_update(C, ptr, prop);
				
				return 1;
			}
		}
	}
	
	return 0;
}
Exemple #4
0
static int act_new_exec(bContext *C, wmOperator *op)
{
	bAction *action;
	PointerRNA ptr, idptr;
	PropertyRNA *prop;

	// XXX need to restore behaviour to copy old actions...
	action= add_empty_action("Action");

	/* hook into UI */
	uiIDContextProperty(C, &ptr, &prop);

	if(prop) {
		/* when creating new ID blocks, use is already 1, but RNA
		 * pointer se also increases user, so this compensates it */
		action->id.us--;

		RNA_id_pointer_create(&action->id, &idptr);
		RNA_property_pointer_set(&ptr, prop, idptr);
		RNA_property_update(C, &ptr, prop);
	}

	/* set notifier that keyframes have changed */
	WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
	
	return OPERATOR_FINISHED;
}
Exemple #5
0
static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr;
	PropertyRNA *prop;
	int success= 0;
	int index, all = RNA_boolean_get(op->ptr, "all");

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* if there is a valid property that is editable... */
	if (ptr.data && prop) {
		CollectionPointerLink *link;
		ListBase lb;

		if(copy_to_selected_list(C, &ptr, &lb)) {
			for(link= lb.first; link; link=link->next) {
				if(link->ptr.data != ptr.data && RNA_property_editable(&link->ptr, prop)) {
					if(RNA_property_copy(&link->ptr, &ptr, prop, (all)? -1: index)) {
						RNA_property_update(C, &link->ptr, prop);
						success= 1;
					}
				}
			}

			BLI_freelistN(&lb);
		}
	}
	
	return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
/**
 * called from both exec & poll
 *
 * \note: normally we wouldn't call a loop from within a poll function,
 * However this is a special case, and for regular poll calls, getting
 * the context from the button will fail early.
 */
static bool copy_to_selected_button(bContext *C, bool all, bool poll)
{
	PointerRNA ptr, lptr, idptr;
	PropertyRNA *prop, *lprop;
	bool success = false;
	int index;

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);

	/* if there is a valid property that is editable... */
	if (ptr.data && prop) {
		char *path = NULL;
		bool use_path;
		CollectionPointerLink *link;
		ListBase lb;

		if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
			return success;

		if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
			for (link = lb.first; link; link = link->next) {
				if (link->ptr.data != ptr.data) {
					if (use_path) {
						lprop = NULL;
						RNA_id_pointer_create(link->ptr.id.data, &idptr);
						RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
					}
					else {
						lptr = link->ptr;
						lprop = prop;
					}

					if (lprop == prop) {
						if (RNA_property_editable(&lptr, lprop)) {
							if (poll) {
								success = true;
								break;
							}
							else {
								if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
									RNA_property_update(C, &lptr, prop);
									success = true;
								}
							}
						}
					}
				}
			}

			if (path)
				MEM_freeN(path);
		}

		BLI_freelistN(&lb);
	}

	return success;
}
static void eyedropper_colorband_apply(bContext *C, wmOperator *op)
{
	EyedropperColorband *eye = op->customdata;
	/* Always filter, avoids noise in resulting color-band. */
	bool filter_samples = true;
	BKE_colorband_init_from_table_rgba(eye->color_band, eye->color_buffer, eye->color_buffer_len, filter_samples);
	RNA_property_update(C, &eye->ptr, eye->prop);
}
Exemple #8
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;
}
static int copy_to_selected_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr, lptr, idptr;
	PropertyRNA *prop, *lprop;
	int success = 0;
	int index, all = RNA_boolean_get(op->ptr, "all");

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* if there is a valid property that is editable... */
	if (ptr.data && prop) {
		char *path = NULL;
		int use_path;
		CollectionPointerLink *link;
		ListBase lb;

		if (!copy_to_selected_list(C, &ptr, &lb, &use_path))
			return success;

		if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) {
			for (link = lb.first; link; link = link->next) {
				if (link->ptr.data != ptr.data) {
					if (use_path) {
						lprop = NULL;
						RNA_id_pointer_create(link->ptr.id.data, &idptr);
						RNA_path_resolve(&idptr, path, &lptr, &lprop);
					}
					else {
						lptr = link->ptr;
						lprop = prop;
					}

					if (lprop == prop) {
						if (RNA_property_editable(&lptr, lprop)) {
							if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) {
								RNA_property_update(C, &lptr, prop);
								success = 1;
							}
						}
					}
				}
			}

			if (path)
				MEM_freeN(path);
		}

		BLI_freelistN(&lb);
	}
	
	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
Exemple #10
0
static void rna_update_cb(bContext *C, void *arg_cb, void *UNUSED(arg))
{
	RNAUpdateCb *cb = (RNAUpdateCb *)arg_cb;

	/* ideally this would be done by RNA itself, but there we have
	 * no image user available, so we just update this flag here */
	cb->iuser->ok = 1;

	/* we call update here on the pointer property, this way the
	 * owner of the image pointer can still define it's own update
	 * and notifier */
	RNA_property_update(C, &cb->ptr, cb->prop);
}
/* sets the ID, returns success */
static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id)
{
	PointerRNA ptr_value;

	RNA_id_pointer_create(id, &ptr_value);

	RNA_property_pointer_set(&ddr->ptr, ddr->prop, ptr_value);

	RNA_property_update(C, &ddr->ptr, ddr->prop);

	ptr_value = RNA_property_pointer_get(&ddr->ptr, ddr->prop);

	return (ptr_value.id.data == id);
}
Exemple #12
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;
}
Exemple #13
0
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports)
{
	ScrArea *sa = CTX_wm_area(C);
	
	/* If the old action only has a single user (that it's about to lose),
	 * warn user about it
	 *
	 * TODO: Maybe we should just save it for them? But then, there's the problem of
	 *       trying to get rid of stuff that's actually unwanted!
	 */
	if (act->id.us == 1) {
		BKE_reportf(reports, RPT_WARNING,
		            "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
		            act->id.name + 2);
	}
	
	/* If in Tweak Mode, don't unlink. Instead, this 
	 * becomes a shortcut to exit Tweak Mode instead
	 */
	if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
		/* Exit Tweak Mode */
		BKE_nla_tweakmode_exit(adt);
		
		/* Flush this to the Action Editor (if that's where this change was initiated) */
		if (sa->spacetype == SPACE_ACTION) {
			actedit_change_action(C, NULL);
		}
	}
	else {
		/* Unlink normally - Setting it to NULL should be enough to get the old one unlinked */
		if (sa->spacetype == SPACE_ACTION) {
			/* clear action editor -> action */
			actedit_change_action(C, NULL);
		}
		else {
			/* clear AnimData -> action */
			PointerRNA ptr;
			PropertyRNA *prop;
			
			/* create AnimData RNA pointers */
			RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
			prop = RNA_struct_find_property(&ptr, "action");
			
			/* clear... */
			RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
			RNA_property_update(C, &ptr, prop);
		}
	}
}
Exemple #14
0
static int act_new_exec(bContext *C, wmOperator *UNUSED(op))
{
	PointerRNA ptr, idptr;
	PropertyRNA *prop;

	/* hook into UI */
	uiIDContextProperty(C, &ptr, &prop);
	
	if (prop) {
		bAction *action = NULL, *oldact = NULL;
		PointerRNA oldptr;
		
		/* create action - the way to do this depends on whether we've got an
		 * existing one there already, in which case we make a copy of it
		 * (which is useful for "versioning" actions within the same file)
		 */
		oldptr = RNA_property_pointer_get(&ptr, prop);
		oldact = (bAction *)oldptr.id.data;
		
		if (oldact && GS(oldact->id.name) == ID_AC) {
			/* make a copy of the existing action */
			action = BKE_action_copy(oldact);
		}
		else {
			Main *bmain = CTX_data_main(C);

			/* just make a new (empty) action */
			action = add_empty_action(bmain, "Action");
		}
		
		/* when creating new ID blocks, use is already 1 (fake user), 
		 * but RNA pointer use also increases user, so this compensates it 
		 */
		action->id.us--;
		
		RNA_id_pointer_create(&action->id, &idptr);
		RNA_property_pointer_set(&ptr, prop, idptr);
		RNA_property_update(C, &ptr, prop);
	}
	
	/* set notifier that keyframes have changed */
	WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
	
	return OPERATOR_FINISHED;
}
Exemple #15
0
/* Change the active action used by the action editor */
static void actedit_change_action(bContext *C, bAction *act)
{
	bScreen *screen = CTX_wm_screen(C);
	SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C);
	
	PointerRNA ptr, idptr;
	PropertyRNA *prop;
	
	/* create RNA pointers and get the property */
	RNA_pointer_create(&screen->id, &RNA_SpaceDopeSheetEditor, saction, &ptr);
	prop = RNA_struct_find_property(&ptr, "action");
	
	/* NOTE: act may be NULL here, so better to just use a cast here */
	RNA_id_pointer_create((ID *)act, &idptr);
	
	/* set the new pointer, and force a refresh */
	RNA_property_pointer_set(&ptr, prop, idptr);
	RNA_property_update(C, &ptr, prop);
}
/* sets the sample color RGB, maintaining A */
static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3])
{
	float col_conv[4];

	/* to maintain alpha */
	RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);

	/* convert from display space to linear rgb space */
	if (eye->display) {
		copy_v3_v3(col_conv, col);
		IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display);
	}
	else {
		copy_v3_v3(col_conv, col);
	}

	RNA_property_float_set_array(&eye->ptr, eye->prop, col_conv);

	RNA_property_update(C, &eye->ptr, eye->prop);
}
Exemple #17
0
static int reset_default_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr;
	PropertyRNA *prop;
	int success= 0;
	int index, all = RNA_boolean_get(op->ptr, "all");

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* if there is a valid property that is editable... */
	if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
		if(RNA_property_reset(&ptr, prop, (all)? -1: index)) {
			/* perform updates required for this property */
			RNA_property_update(C, &ptr, prop);
			success= 1;
		}
	}
	
	return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
static int operator_button_property_finish(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
{
	ID *id = ptr->id.data;

	/* perform updates required for this property */
	RNA_property_update(C, ptr, prop);

	/* as if we pressed the button */
	uiContextActivePropertyHandle(C);

	/* Since we don't want to undo _all_ edits to settings, eg window
	 * edits on the screen or on operator settings.
	 * it might be better to move undo's inline - campbell */
	if (id && ID_CHECK_UNDO(id)) {
		/* do nothing, go ahead with undo */
		return OPERATOR_FINISHED;
	}
	else {
		return OPERATOR_CANCELLED;
	}
}
Exemple #19
0
static int reset_default_button_exec(bContext *C, wmOperator *op)
{
	PointerRNA ptr;
	PropertyRNA *prop;
	int success= 0;
	int index, all = RNA_boolean_get(op->ptr, "all");

	/* try to reset the nominated setting to its default value */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* if there is a valid property that is editable... */
	if (ptr.data && prop && RNA_property_editable(&ptr, prop)) {
		if(RNA_property_reset(&ptr, prop, (all)? -1: index)) {
			/* perform updates required for this property */
			RNA_property_update(C, &ptr, prop);

			/* as if we pressed the button */
			uiContextActivePropertyHandle(C);

			success= 1;
		}
	}

	/* Since we dont want to undo _all_ edits to settings, eg window
	 * edits on the screen or on operator settings.
	 * it might be better to move undo's inline - campbell */
	if(success) {
		ID *id= ptr.id.data;
		if(id && ID_CHECK_UNDO(id)) {
			/* do nothing, go ahead with undo */
		}
		else {
			return OPERATOR_CANCELLED;
		}
	}
	/* end hack */

	return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED;
}
Exemple #20
0
static void eyedropper_sample(bContext *C, Eyedropper *eye, int mx, int my)
{
	if(RNA_property_type(eye->prop) == PROP_FLOAT) {
		const int color_manage = CTX_data_scene(C)->r.color_mgt_flag & R_COLOR_MANAGEMENT;
		float col[4];
	
		RNA_property_float_get_array(&eye->ptr, eye->prop, col);
		
		glReadBuffer(GL_FRONT);
		glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, col);
		glReadBuffer(GL_BACK);
	
		if (RNA_property_array_length(&eye->ptr, eye->prop) < 3) return;

		/* convert from screen (srgb) space to linear rgb space */
		if (color_manage && RNA_property_subtype(eye->prop) == PROP_COLOR)
			srgb_to_linearrgb_v3_v3(col, col);
		
		RNA_property_float_set_array(&eye->ptr, eye->prop, col);
		
		RNA_property_update(C, &eye->ptr, eye->prop);
	}
}
static int eyedropper_colorband_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
  EyedropperColorband *eye = op->customdata;
  /* handle modal keymap */
  if (event->type == EVT_MODAL_MAP) {
    switch (event->val) {
      case EYE_MODAL_POINT_CANCEL:
        eyedropper_colorband_cancel(C, op);
        return OPERATOR_CANCELLED;
      case EYE_MODAL_POINT_CONFIRM:
        eyedropper_colorband_apply(C, op);
        eyedropper_colorband_exit(C, op);
        return OPERATOR_FINISHED;
      case EYE_MODAL_POINT_REMOVE_LAST:
        if (eye->color_buffer_len > 0) {
          eye->color_buffer_len -= 1;
          eyedropper_colorband_apply(C, op);
        }
        break;
      case EYE_MODAL_POINT_SAMPLE:
        eyedropper_colorband_sample_point(C, eye, event->x, event->y);
        eyedropper_colorband_apply(C, op);
        if (eye->color_buffer_len == MAXCOLORBAND) {
          eyedropper_colorband_exit(C, op);
          return OPERATOR_FINISHED;
        }
        break;
      case EYE_MODAL_SAMPLE_RESET:
        *eye->color_band = eye->init_color_band;
        RNA_property_update(C, &eye->ptr, eye->prop);
        eye->color_buffer_len = 0;
        break;
    }
  }
  return OPERATOR_RUNNING_MODAL;
}
Exemple #22
0
void ED_animedit_unlink_action(bContext *C, ID *id, AnimData *adt, bAction *act, ReportList *reports, bool force_delete)
{
	ScrArea *sa = CTX_wm_area(C);
	
	/* If the old action only has a single user (that it's about to lose),
	 * warn user about it
	 *
	 * TODO: Maybe we should just save it for them? But then, there's the problem of
	 *       trying to get rid of stuff that's actually unwanted!
	 */
	if (act->id.us == 1) {
		BKE_reportf(reports, RPT_WARNING,
		            "Action '%s' will not be saved, create Fake User or Stash in NLA Stack to retain",
		            act->id.name + 2);
	}
	
	/* Clear Fake User and remove action stashing strip (if present) */
	if (force_delete) {
		/* Remove stashed strip binding this action to this datablock */
		/* XXX: we cannot unlink it from *OTHER* datablocks that may also be stashing it,
		 * but GE users only seem to use/care about single-object binding for now so this
		 * should be fine
		 */
		if (adt) {
			NlaTrack *nlt, *nlt_next;
			NlaStrip *strip, *nstrip;
			
			for (nlt = adt->nla_tracks.first; nlt; nlt = nlt_next) {
				nlt_next = nlt->next;
				
				if (strstr(nlt->name, DATA_("[Action Stash]"))) {
					for (strip = nlt->strips.first; strip; strip = nstrip) {
						nstrip = strip->next;
						
						if (strip->act == act) {
							/* Remove this strip, and the track too if it doesn't have anything else */
							free_nlastrip(&nlt->strips, strip);
							
							if (nlt->strips.first == NULL) {
								BLI_assert(nstrip == NULL);
								free_nlatrack(&adt->nla_tracks, nlt);
							}
						}
					}
				}
			}
		}
		
		/* Clear Fake User */
		id_fake_user_clear(&act->id);
	}
	
	/* If in Tweak Mode, don't unlink. Instead, this 
	 * becomes a shortcut to exit Tweak Mode instead
	 */
	if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
		/* Exit Tweak Mode */
		BKE_nla_tweakmode_exit(adt);
		
		/* Flush this to the Action Editor (if that's where this change was initiated) */
		if (sa->spacetype == SPACE_ACTION) {
			actedit_change_action(C, NULL);
		}
	}
	else {
		/* Unlink normally - Setting it to NULL should be enough to get the old one unlinked */
		if (sa->spacetype == SPACE_ACTION) {
			/* clear action editor -> action */
			actedit_change_action(C, NULL);
		}
		else {
			/* clear AnimData -> action */
			PointerRNA ptr;
			PropertyRNA *prop;
			
			/* create AnimData RNA pointers */
			RNA_pointer_create(id, &RNA_AnimData, adt, &ptr);
			prop = RNA_struct_find_property(&ptr, "action");
			
			/* clear... */
			RNA_property_pointer_set(&ptr, prop, PointerRNA_NULL);
			RNA_property_update(C, &ptr, prop);
		}
	}
}
Exemple #23
0
static int action_new_exec(bContext *C, wmOperator *UNUSED(op))
{
	PointerRNA ptr, idptr;
	PropertyRNA *prop;
	
	/* hook into UI */
	UI_context_active_but_prop_get_templateID(C, &ptr, &prop);
	
	if (prop) {
		bAction *action = NULL, *oldact = NULL;
		AnimData *adt = NULL;
		PointerRNA oldptr;
		
		oldptr = RNA_property_pointer_get(&ptr, prop);
		oldact = (bAction *)oldptr.id.data;
		
		/* stash the old action to prevent it from being lost */
		if (ptr.type == &RNA_AnimData) {
			adt = ptr.data;
		}
		else if (ptr.type == &RNA_SpaceDopeSheetEditor) {
			adt = ED_actedit_animdata_from_context(C);
		}
		
		/* Perform stashing operation - But only if there is an action */
		if (adt && oldact) {
			/* stash the action */
			if (BKE_nla_action_stash(adt)) {
				/* The stash operation will remove the user already
				 * (and unlink the action from the AnimData action slot).
				 * Hence, we must unset the ref to the action in the
				 * action editor too (if this is where we're being called from)
				 * first before setting the new action once it is created,
				 * or else the user gets decremented twice!
				 */
				if (ptr.type == &RNA_SpaceDopeSheetEditor) {
					SpaceAction *saction = (SpaceAction *)ptr.data;
					saction->action = NULL;
				}
			}
			else {
				//printf("WARNING: Failed to stash %s. It may already exist in the NLA stack though\n", oldact->id.name);
			}
		}
		
		/* create action */
		action = action_create_new(C, oldact);
		
		/* set this new action
		 * NOTE: we can't use actedit_change_action, as this function is also called from the NLA
		 */
		RNA_id_pointer_create(&action->id, &idptr);
		RNA_property_pointer_set(&ptr, prop, idptr);
		RNA_property_update(C, &ptr, prop);
	}
	
	/* set notifier that keyframes have changed */
	WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
	
	return OPERATOR_FINISHED;
}
Exemple #24
0
/**
 * called from both exec & poll
 *
 * \note: normally we wouldn't call a loop from within a poll function,
 * However this is a special case, and for regular poll calls, getting
 * the context from the button will fail early.
 */
static bool copy_to_selected_button(bContext *C, bool all, bool poll)
{
  Main *bmain = CTX_data_main(C);
  PointerRNA ptr, lptr, idptr;
  PropertyRNA *prop, *lprop;
  bool success = false;
  int index;

  /* try to reset the nominated setting to its default value */
  UI_context_active_but_prop_get(C, &ptr, &prop, &index);

  /* if there is a valid property that is editable... */
  if (ptr.data && prop) {
    char *path = NULL;
    bool use_path_from_id;
    CollectionPointerLink *link;
    ListBase lb = {NULL};

    if (UI_context_copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path) &&
        !BLI_listbase_is_empty(&lb)) {
      for (link = lb.first; link; link = link->next) {
        if (link->ptr.data != ptr.data) {
          if (use_path_from_id) {
            /* Path relative to ID. */
            lprop = NULL;
            RNA_id_pointer_create(link->ptr.id.data, &idptr);
            RNA_path_resolve_property(&idptr, path, &lptr, &lprop);
          }
          else if (path) {
            /* Path relative to elements from list. */
            lprop = NULL;
            RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop);
          }
          else {
            lptr = link->ptr;
            lprop = prop;
          }

          if (lptr.data == ptr.data) {
            /* lptr might not be the same as link->ptr! */
            continue;
          }

          if (lprop == prop) {
            if (RNA_property_editable(&lptr, lprop)) {
              if (poll) {
                success = true;
                break;
              }
              else {
                if (RNA_property_copy(bmain, &lptr, &ptr, prop, (all) ? -1 : index)) {
                  RNA_property_update(C, &lptr, prop);
                  success = true;
                }
              }
            }
          }
        }
      }
    }
    MEM_SAFE_FREE(path);
    BLI_freelistN(&lb);
  }

  return success;
}
/* sets the sample depth RGB, maintaining A */
static void depthdropper_depth_set(bContext *C, DepthDropper *ddr, const float depth)
{
	RNA_property_float_set(&ddr->ptr, ddr->prop, depth);
	RNA_property_update(C, &ddr->ptr, ddr->prop);
}
Exemple #26
0
static int open_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	bScreen *screen = CTX_wm_screen(C);
	Main *bmain = CTX_data_main(C);
	PropertyPointerRNA *pprop;
	PointerRNA idptr;
	MovieClip *clip = NULL;
	char str[FILE_MAX];

	if (RNA_collection_length(op->ptr, "files")) {
		PointerRNA fileptr;
		PropertyRNA *prop;
		char dir_only[FILE_MAX], file_only[FILE_MAX];
		int relative = RNA_boolean_get(op->ptr, "relative_path");

		RNA_string_get(op->ptr, "directory", dir_only);
		if (relative)
			BLI_path_rel(dir_only, G.main->name);

		prop = RNA_struct_find_property(op->ptr, "files");
		RNA_property_collection_lookup_int(op->ptr, prop, 0, &fileptr);
		RNA_string_get(&fileptr, "name", file_only);

		BLI_join_dirfile(str, sizeof(str), dir_only, file_only);
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "No files selected to be opened");

		return OPERATOR_CANCELLED;
	}

	/* default to frame 1 if there's no scene in context */

	errno = 0;

	clip = BKE_movieclip_file_add(bmain, str);

	if (!clip) {
		if (op->customdata)
			MEM_freeN(op->customdata);

		BKE_reportf(op->reports, RPT_ERROR, "Cannot read '%s': %s", str,
		            errno ? strerror(errno) : TIP_("unsupported movie clip format"));

		return OPERATOR_CANCELLED;
	}

	if (!op->customdata)
		open_init(C, op);

	/* hook into UI */
	pprop = op->customdata;

	if (pprop->prop) {
		/* when creating new ID blocks, use is already 1, but RNA
		 * pointer se also increases user, so this compensates it */
		clip->id.us--;

		RNA_id_pointer_create(&clip->id, &idptr);
		RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
		RNA_property_update(C, &pprop->ptr, pprop->prop);
	}
	else if (sc) {
		ED_space_clip_set_clip(C, screen, sc, clip);
	}

	WM_event_add_notifier(C, NC_MOVIECLIP | NA_ADDED, clip);

	MEM_freeN(op->customdata);

	return OPERATOR_FINISHED;
}