static char *view3d_modeselect_pup(Scene *scene) { Object *ob = OBACT; static char string[512]; const char *title = IFACE_("Mode: %t"); char *str = string; BLI_strncpy(str, title, sizeof(string)); str += modeselect_addmode(str, N_("Object Mode"), OB_MODE_OBJECT, ICON_OBJECT_DATA); if (ob == NULL || ob->data == NULL) return string; if (ob->id.lib) return string; if (!((ID *)ob->data)->lib) { /* if active object is editable */ if (ob->type == OB_ARMATURE) { if (ob->mode & OB_MODE_POSE) str += modeselect_addmode(str, N_("Edit Mode"), OB_MODE_EDIT | OB_MODE_POSE, ICON_EDITMODE_HLT); else str += modeselect_addmode(str, N_("Edit Mode"), OB_MODE_EDIT, ICON_EDITMODE_HLT); } else if (OB_TYPE_SUPPORT_EDITMODE(ob->type)) { str += modeselect_addmode(str, N_("Edit Mode"), OB_MODE_EDIT, ICON_EDITMODE_HLT); } if (ob->type == OB_MESH) { str += modeselect_addmode(str, N_("Sculpt Mode"), OB_MODE_SCULPT, ICON_SCULPTMODE_HLT); str += modeselect_addmode(str, N_("Vertex Paint"), OB_MODE_VERTEX_PAINT, ICON_VPAINT_HLT); str += modeselect_addmode(str, N_("Texture Paint"), OB_MODE_TEXTURE_PAINT, ICON_TPAINT_HLT); str += modeselect_addmode(str, N_("Weight Paint"), OB_MODE_WEIGHT_PAINT, ICON_WPAINT_HLT); } } /* if active object is an armature */ if (ob->type == OB_ARMATURE) { str += modeselect_addmode(str, N_("Pose Mode"), OB_MODE_POSE, ICON_POSE_HLT); } if (ob->particlesystem.first || modifiers_findByType(ob, eModifierType_Cloth) || modifiers_findByType(ob, eModifierType_Softbody)) { str += modeselect_addmode(str, N_("Particle Mode"), OB_MODE_PARTICLE_EDIT, ICON_PARTICLEMODE); } (void)str; return (string); }
/* name optionally, function used to check for operator redo panel */ int ED_undo_valid(const bContext *C, const char *undoname) { Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); ScrArea *sa = CTX_wm_area(C); if (sa && sa->spacetype == SPACE_IMAGE) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { return 1; } } if (sa && (sa->spacetype == SPACE_TEXT)) { return 1; } else if (obedit) { if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) { return undo_editmode_valid(undoname); } } else { /* if below tests fail, global undo gets executed */ if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) { if (ED_undo_paint_valid(UNDO_PAINT_IMAGE, undoname)) return 1; } else if (obact && obact->mode & OB_MODE_SCULPT) { if (ED_undo_paint_valid(UNDO_PAINT_MESH, undoname)) return 1; } else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { return PE_undo_valid(CTX_data_scene(C)); } if (U.uiflag & USER_GLOBALUNDO) { return BKE_undo_valid(undoname); } } return 0; }
static int get_undo_system(bContext *C) { Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); ScrArea *sa = CTX_wm_area(C); /* first check for editor undo */ if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } } /* find out which undo system */ if (obedit) { if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) { return UNDOSYSTEM_EDITMODE; } } else { if (obact) { if (obact->mode & OB_MODE_PARTICLE_EDIT) return UNDOSYSTEM_PARTICLE; else if (obact->mode & OB_MODE_TEXTURE_PAINT) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } else if (obact->mode & OB_MODE_SCULPT) { if (!ED_undo_paint_empty(UNDO_PAINT_MESH)) return UNDOSYSTEM_SCULPT; } } if (U.uiflag & USER_GLOBALUNDO) return UNDOSYSTEM_GLOBAL; } return 0; }
/* note: also check undo_history_exec() in bottom if you change notifiers */ static int ed_undo_step(bContext *C, int step, const char *undoname) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); Scene *scene = CTX_data_scene(C); Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); ScrArea *sa = CTX_wm_area(C); /* undo during jobs are running can easily lead to freeing data using by jobs, * or they can just lead to freezing job in some other cases */ if (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY)) { return OPERATOR_CANCELLED; } /* grease pencil can be can be used in plenty of spaces, so check it first */ if (ED_gpencil_session_active()) { return ED_undo_gpencil_step(C, step, undoname); } if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname) && undoname) { if (U.uiflag & USER_GLOBALUNDO) { ED_viewport_render_kill_jobs(C, true); BKE_undo_name(C, undoname); } } WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_FINISHED; } } if (sa && (sa->spacetype == SPACE_TEXT)) { ED_text_undo_step(C, step); } else if (obedit) { if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) { if (undoname) undo_editmode_name(C, undoname); else undo_editmode_step(C, step); WM_event_add_notifier(C, NC_GEOM | ND_DATA, NULL); } } else { /* Note: we used to do a fall-through here where if the * mode-specific undo system had no more steps to undo (or * redo), the global undo would run. * * That was inconsistent with editmode, and also makes for * unecessarily tricky interaction with the other undo * systems. */ if (obact && obact->mode & OB_MODE_TEXTURE_PAINT) { ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step, undoname); } else if (obact && obact->mode & OB_MODE_SCULPT) { ED_undo_paint_step(C, UNDO_PAINT_MESH, step, undoname); } else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { if (step == 1) PE_undo(scene); else PE_redo(scene); } else if (U.uiflag & USER_GLOBALUNDO) { // note python defines not valid here anymore. //#ifdef WITH_PYTHON // XXX BPY_scripts_clear_pyobjects(); //#endif /* for global undo/redo we should just clear the editmode stack */ /* for example, texface stores image pointers */ undo_editmode_clear(); ED_viewport_render_kill_jobs(C, true); if (undoname) BKE_undo_name(C, undoname); else BKE_undo_step(C, step); scene = CTX_data_scene(C); WM_event_add_notifier(C, NC_SCENE | ND_LAYER_CONTENT, scene); } } WM_event_add_notifier(C, NC_WINDOW, NULL); if (win) { win->addmousemove = true; } return OPERATOR_FINISHED; }