Sculpt: split generic part of image paint undo system into separate
[blender-staging.git] / source / blender / editors / util / undo.c
index c7d4d1a2719a7485c3f9501108618689f97f0b56..18e3304c1910a48e08da37156a630ce2d1d4c382 100644 (file)
@@ -47,6 +47,7 @@
 #include "BKE_depsgraph.h"
 #include "BKE_global.h"
 #include "BKE_object.h"
+#include "BKE_text.h"
 
 #include "BLI_blenlib.h"
 #include "BLI_editVert.h"
 
 #include "BKE_utildefines.h"
 
-#include "ED_util.h"
+#include "ED_armature.h"
+#include "ED_particle.h"
+#include "ED_curve.h"
+#include "ED_mball.h"
 #include "ED_mesh.h"
+#include "ED_object.h"
+#include "ED_screen.h"
+#include "ED_sculpt.h"
+#include "ED_util.h"
+#include "ED_text.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
 
 #include "UI_interface.h"
 #include "UI_resources.h"
 
-/* ***************** generic undo system ********************* */
+#include "util_intern.h"
 
-/* ********* XXX **************** */
-static void undo_push_curve() {}
-static void undo_push_font() {}
-static void undo_push_mball() {}
-static void undo_push_lattice() {}
-static void undo_push_armature() {}
-static void PE_undo_push() {}
-static void PE_undo() {}
-static void PE_redo() {}
-static void PE_undo_menu() {}
-static void undo_imagepaint_step() {}
-static void sound_initialize_sounds() {}
-/* ********* XXX **************** */
+/* ***************** generic undo system ********************* */
 
 void ED_undo_push(bContext *C, char *str)
 {
-       if(G.obedit) {
+       wmWindowManager *wm= CTX_wm_manager(C);
+       Object *obedit= CTX_data_edit_object(C);
+       Object *obact= CTX_data_active_object(C);
+
+       if(obedit) {
                if (U.undosteps == 0) return;
                
-               if(G.obedit->type==OB_MESH)
-                       undo_push_mesh(str);
-               else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
-                       undo_push_curve(str);
-               else if (G.obedit->type==OB_FONT)
-                       undo_push_font(str);
-               else if (G.obedit->type==OB_MBALL)
-                       undo_push_mball(str);
-               else if (G.obedit->type==OB_LATTICE)
-                       undo_push_lattice(str);
-               else if (G.obedit->type==OB_ARMATURE)
-                       undo_push_armature(str);
+               if(obedit->type==OB_MESH)
+                       undo_push_mesh(C, str);
+               else if ELEM(obedit->type, OB_CURVE, OB_SURF)
+                       undo_push_curve(C, str);
+               else if (obedit->type==OB_FONT)
+                       undo_push_font(C, str);
+               else if (obedit->type==OB_MBALL)
+                       undo_push_mball(C, str);
+               else if (obedit->type==OB_LATTICE)
+                       undo_push_lattice(C, str);
+               else if (obedit->type==OB_ARMATURE)
+                       undo_push_armature(C, str);
        }
-       else if(G.f & G_PARTICLEEDIT) {
+       else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
                if (U.undosteps == 0) return;
                
-               PE_undo_push(str);
+               PE_undo_push(CTX_data_scene(C), str);
        }
        else {
                if(U.uiflag & USER_GLOBALUNDO) 
                        BKE_write_undo(C, str);
        }
-}
-
-static void undo_do(bContext *C)
-{
-       if(U.uiflag & USER_GLOBALUNDO) {
-#ifndef DISABLE_PYTHON
-// XXX         BPY_scripts_clear_pyobjects();
-#endif
-               BKE_undo_step(C, 1);
-               sound_initialize_sounds();
-       }
        
+       if(wm->file_saved) {
+               wm->file_saved= 0;
+               WM_event_add_notifier(C, NC_WM|ND_DATACHANGED, NULL);
+       }
 }
 
-void ED_undo(bContext *C)
+static int ed_undo_step(bContext *C, int step, const char *undoname)
 {      
+       Object *obedit= CTX_data_edit_object(C);
+       Object *obact= CTX_data_active_object(C);
        ScrArea *sa= CTX_wm_area(C);
-       
-       if(G.obedit) {
-               if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
-                       undo_editmode_step(1);
-       }
-       else {
-               if(G.f & G_TEXTUREPAINT)
-                       undo_imagepaint_step(1);
-               else if(sa->spacetype==SPACE_IMAGE) {
-                       SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
-                       if(sima->flag & SI_DRAWTOOL)
-                               undo_imagepaint_step(1);
-                       else
-                               undo_do(C);
-               }
-               else if(G.f & G_PARTICLEEDIT)
-                       PE_undo();
-               else {
-                       undo_do(C);
+
+       if(sa && sa->spacetype==SPACE_IMAGE) {
+               SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
+               
+               if((obact && obact->mode & OB_MODE_TEXTURE_PAINT) || sima->flag & SI_DRAWTOOL) {
+                       ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step);
+
+                       WM_event_add_notifier(C, NC_WINDOW, NULL);
+                       return OPERATOR_FINISHED;
                }
        }
-}
 
-void ED_redo(bContext *C)
-{
-       ScrArea *sa= CTX_wm_area(C);
-       
-       if(G.obedit) {
-               if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
-                       undo_editmode_step(-1);
+       if(sa && sa->spacetype==SPACE_TEXT) {
+               ED_text_undo_step(C, step);
+       }
+       else if(obedit) {
+               if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE) {
+                       if(undoname)
+                               undo_editmode_name(C, undoname);
+                       else
+                               undo_editmode_step(C, step);
+               }
        }
        else {
-               if(G.f & G_TEXTUREPAINT)
-                       undo_imagepaint_step(-1);
-               else if(sa->spacetype==SPACE_IMAGE) {
-                       SpaceImage *sima= (SpaceImage *)sa->spacedata.first;
-                       if(sima->flag & SI_DRAWTOOL)
-                               undo_imagepaint_step(-1);
-                       else {
-                               BKE_undo_step(C, -1);
-                               sound_initialize_sounds();
-                       }
+               int do_glob_undo= 0;
+               
+               if(obact && obact->mode & OB_MODE_TEXTURE_PAINT)
+                       ED_undo_paint_step(C, UNDO_PAINT_IMAGE, step);
+               else if(obact && obact->mode & OB_MODE_PARTICLE_EDIT) {
+                       if(step==1)
+                               PE_undo(CTX_data_scene(C));
+                       else
+                               PE_redo(CTX_data_scene(C));
                }
-               else if(G.f & G_PARTICLEEDIT)
-                       PE_redo();
                else {
-                       /* includes faceselect now */
+                       do_glob_undo= 1;
+               }
+               
+               if(do_glob_undo) {
                        if(U.uiflag & USER_GLOBALUNDO) {
-                               BKE_undo_step(C, -1);
-                               sound_initialize_sounds();
+#ifndef DISABLE_PYTHON
+                               // XXX          BPY_scripts_clear_pyobjects();
+#endif
+                               if(undoname)
+                                       BKE_undo_name(C, undoname);
+                               else
+                                       BKE_undo_step(C, step);
                        }
+                       
                }
        }
+       
+       WM_event_add_notifier(C, NC_WINDOW, NULL);
+       
+       return OPERATOR_FINISHED;
+}
+
+void ED_undo_pop(bContext *C)
+{
+       ed_undo_step(C, 1, NULL);
+}
+void ED_undo_redo(bContext *C)
+{
+       ed_undo_step(C, -1, NULL);
+}
+
+void ED_undo_push_op(bContext *C, wmOperator *op)
+{
+       /* in future, get undo string info? */
+       ED_undo_push(C, op->type->name);
+}
+
+void ED_undo_pop_op(bContext *C, wmOperator *op)
+{
+       /* search back a couple of undo's, in case something else added pushes */
+       ed_undo_step(C, 0, op->type->name);
+}
+
+static int ed_undo_exec(bContext *C, wmOperator *op)
+{
+       /* "last operator" should disappear, later we can tie ths with undo stack nicer */
+       WM_operator_stack_clear(C);
+       return ed_undo_step(C, 1, NULL);
+}
+
+static int ed_redo_exec(bContext *C, wmOperator *op)
+{
+       return ed_undo_step(C, -1, NULL);
 }
 
 void ED_undo_menu(bContext *C)
 {
-       if(G.obedit) {
-               if ELEM7(G.obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
-                       undo_editmode_menu();
+       Object *obedit= CTX_data_edit_object(C);
+       Object *obact= CTX_data_active_object(C);
+       
+       if(obedit) {
+               //if ELEM7(obedit->type, OB_MESH, OB_FONT, OB_CURVE, OB_SURF, OB_MBALL, OB_LATTICE, OB_ARMATURE)
+               //      undo_editmode_menu();
        }
        else {
-               if(G.f & G_PARTICLEEDIT)
-                       PE_undo_menu();
+               if(obact && obact->mode & OB_MODE_PARTICLE_EDIT)
+                       PE_undo_menu(CTX_data_scene(C), CTX_data_active_object(C));
                else if(U.uiflag & USER_GLOBALUNDO) {
                        char *menu= BKE_undo_menu_string();
                        if(menu) {
@@ -191,10 +228,36 @@ void ED_undo_menu(bContext *C)
                                MEM_freeN(menu);
                                if(event>0) {
                                        BKE_undo_number(C, event);
-                                       sound_initialize_sounds();
                                }
                        }
                }
        }
 }
 
+/* ********************** */
+
+void ED_OT_undo(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Undo";
+    ot->description= "Undo previous action.";
+       ot->idname= "ED_OT_undo";
+       
+       /* api callbacks */
+       ot->exec= ed_undo_exec;
+       ot->poll= ED_operator_screenactive;
+}
+
+void ED_OT_redo(wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Redo";
+    ot->description= "Redo previous action.";
+       ot->idname= "ED_OT_redo";
+       
+       /* api callbacks */
+       ot->exec= ed_redo_exec;
+       ot->poll= ED_operator_screenactive;
+}
+
+