diff options
author | Ton Roosendaal <ton@blender.org> | 2009-01-01 16:15:35 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2009-01-01 16:15:35 +0300 |
commit | e9a3b4f85df2261cafea0bfc9f0a885708cdf9d6 (patch) | |
tree | d4ebc689eb2f61a1af93ccd13b882e55e635c455 /source/blender/editors/util | |
parent | a1c4d1c735c59b5911dbd0d8557b8f2b32263fe5 (diff) |
2.5
- Edit mode Mesh undo/redo back
(undo for editmodes needed recode, todo for curve/lattice/etc)
- Added border select for edit mesh
- Added Akey (de)select all for edit mesh
- Added notifiers for mode changes.
This is also the first trial to dynamically add/remove
keymap handlers, based on modes. For that reason the Object
keymap was split in 2, modal and non-modal. On TABkey, the
view3d listener removes and adds maps.
The view3d keymap still handles generic mouse/border selection.
Internally it will verify modes.
The modes are not re-implemented still... have to move this
to scene context.
Diffstat (limited to 'source/blender/editors/util')
-rw-r--r-- | source/blender/editors/util/ed_util.c | 3 | ||||
-rw-r--r-- | source/blender/editors/util/editmode_undo.c | 80 | ||||
-rw-r--r-- | source/blender/editors/util/undo.c | 83 | ||||
-rw-r--r-- | source/blender/editors/util/util_intern.h | 38 |
4 files changed, 120 insertions, 84 deletions
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 034b8a1576b..6de980beff4 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -52,6 +52,9 @@ void ED_editors_exit(bContext *C) { + /* frees all editmode undos */ + undo_editmode_clear(); + if(CTX_data_edit_object(C)) { Object *ob= CTX_data_edit_object(C); diff --git a/source/blender/editors/util/editmode_undo.c b/source/blender/editors/util/editmode_undo.c index 05813b72ad0..2237f403f01 100644 --- a/source/blender/editors/util/editmode_undo.c +++ b/source/blender/editors/util/editmode_undo.c @@ -61,16 +61,17 @@ Add this in your local code: -void undo_editmode_push(char *name, +void undo_editmode_push(bContext *C, char *name, + void * (*getdata)(bContext *C), // use context to retrieve current editdata void (*freedata)(void *), // pointer to function freeing data - void (*to_editmode)(void *), // data to editmode conversion - void * (*from_editmode)(void)) // editmode to data conversion - int (*validate_undo)(void *)) // check if undo data is still valid + void (*to_editmode)(void *, void *), // data to editmode conversion + void * (*from_editmode)(void *)) // editmode to data conversion + int (*validate_undo)(void *, void *)) // check if undo data is still valid Further exported for UI is: -void undo_editmode_step(int step); // undo and redo +void undo_editmode_step(bContext *C, int step); // undo and redo void undo_editmode_clear(void) // free & clear all data void undo_editmode_menu(void) // history menu @@ -92,10 +93,11 @@ typedef struct UndoElem { void *undodata; uintptr_t undosize; char name[MAXUNDONAME]; + void * (*getdata)(bContext *C); void (*freedata)(void *); - void (*to_editmode)(void *); - void * (*from_editmode)(void); - int (*validate_undo)(void *); + void (*to_editmode)(void *, void *); + void * (*from_editmode)(void *); + int (*validate_undo)(void *, void *); } UndoElem; static ListBase undobase={NULL, NULL}; @@ -104,19 +106,23 @@ static UndoElem *curundo= NULL; /* ********************* xtern api calls ************* */ -static void undo_restore(UndoElem *undo) +static void undo_restore(UndoElem *undo, void *editdata) { if(undo) { - undo->to_editmode(undo->undodata); + undo->to_editmode(undo->undodata, editdata); } } /* name can be a dynamic string */ -void undo_editmode_push(char *name, void (*freedata)(void *), - void (*to_editmode)(void *), void *(*from_editmode)(void), - int (*validate_undo)(void *)) +void undo_editmode_push(bContext *C, char *name, + void * (*getdata)(bContext *C), + void (*freedata)(void *), + void (*to_editmode)(void *, void *), + void *(*from_editmode)(void *), + int (*validate_undo)(void *, void *)) { UndoElem *uel; + void *editdata; int nr; uintptr_t memused, totmem, maxmem; @@ -131,10 +137,11 @@ void undo_editmode_push(char *name, void (*freedata)(void *), } /* make new */ - curundo= uel= MEM_callocN(sizeof(UndoElem), "undo file"); + curundo= uel= MEM_callocN(sizeof(UndoElem), "undo editmode"); strncpy(uel->name, name, MAXUNDONAME-1); BLI_addtail(&undobase, uel); + uel->getdata= getdata; uel->freedata= freedata; uel->to_editmode= to_editmode; uel->from_editmode= from_editmode; @@ -158,7 +165,8 @@ void undo_editmode_push(char *name, void (*freedata)(void *), /* copy */ memused= MEM_get_memory_in_use(); - curundo->undodata= curundo->from_editmode(); + editdata= getdata(C); + curundo->undodata= curundo->from_editmode(editdata); curundo->undosize= MEM_get_memory_in_use() - memused; curundo->ob= G.obedit; curundo->id= G.obedit->id; @@ -190,7 +198,7 @@ void undo_editmode_push(char *name, void (*freedata)(void *), } /* helper to remove clean other objects from undo stack */ -static void undo_clean_stack(void) +static void undo_clean_stack(bContext *C) { UndoElem *uel, *next; int mixed= 0; @@ -200,19 +208,27 @@ static void undo_clean_stack(void) uel= undobase.first; while(uel) { + void *editdata= uel->getdata(C); + int isvalid= 0; next= uel->next; /* for when objects are converted, renamed, or global undo changes pointers... */ - if(uel->type==G.obedit->type && strcmp(uel->id.name, G.obedit->id.name)==0 && - (!uel->validate_undo || uel->validate_undo(uel->undodata))) { - uel->ob= G.obedit; + if(uel->type==G.obedit->type) { + if(strcmp(uel->id.name, G.obedit->id.name)==0) { + if(uel->validate_undo==NULL) + isvalid= 1; + else if(uel->validate_undo(uel->undodata, editdata)) + isvalid= 1; + } } + if(isvalid) + uel->ob= G.obedit; else { mixed= 1; uel->freedata(uel->undodata); BLI_freelinkN(&undobase, uel); } - + uel= next; } @@ -220,14 +236,14 @@ static void undo_clean_stack(void) } /* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ -void undo_editmode_step(int step) +void undo_editmode_step(bContext *C, int step) { /* prevent undo to happen on wrong object, stack can be a mix */ - undo_clean_stack(); + undo_clean_stack(C); if(step==0) { - undo_restore(curundo); + undo_restore(curundo, curundo->getdata(C)); } else if(step==1) { @@ -235,7 +251,7 @@ void undo_editmode_step(int step) else { if(G.f & G_DEBUG) printf("undo %s\n", curundo->name); curundo= curundo->prev; - undo_restore(curundo); + undo_restore(curundo, curundo->getdata(C)); } } else { @@ -243,7 +259,7 @@ void undo_editmode_step(int step) if(curundo==NULL || curundo->next==NULL) error("No more steps to redo"); else { - undo_restore(curundo->next); + undo_restore(curundo->next, curundo->getdata(C)); curundo= curundo->next; if(G.f & G_DEBUG) printf("redo %s\n", curundo->name); } @@ -267,7 +283,7 @@ void undo_editmode_clear(void) } /* based on index nr it does a restore */ -static void undo_number(int nr) +static void undo_number(bContext *C, int nr) { UndoElem *uel; int a=1; @@ -276,19 +292,19 @@ static void undo_number(int nr) if(a==nr) break; } curundo= uel; - undo_editmode_step(0); + undo_editmode_step(C, 0); } /* ************** for interaction with menu/pullown */ -void undo_editmode_menu(void) +void undo_editmode_menu(bContext *C) { UndoElem *uel; DynStr *ds= BLI_dynstr_new(); short event; char *menu; - undo_clean_stack(); // removes other objects from it + undo_clean_stack(C); // removes other objects from it BLI_dynstr_append(ds, "Editmode Undo History %t"); @@ -303,7 +319,7 @@ void undo_editmode_menu(void) // XXX event= pupmenu_col(menu, 20); MEM_freeN(menu); - if(event>0) undo_number(event); + if(event>0) undo_number(C, event); } static void do_editmode_undohistorymenu(bContext *C, void *arg, int event) @@ -311,7 +327,7 @@ static void do_editmode_undohistorymenu(bContext *C, void *arg, int event) if(G.obedit==NULL || event<1) return; - undo_number(event-1); + undo_number(C, event-1); } @@ -322,7 +338,7 @@ uiBlock *editmode_undohistorymenu(bContext *C, uiMenuBlockHandle *handle, void * short yco = 20, menuwidth = 120; short item= 1; - undo_clean_stack(); // removes other objects from it + undo_clean_stack(C); // removes other objects from it block= uiBeginBlock(C, handle->region, "view3d_edit_mesh_undohistorymenu", UI_EMBOSSP, UI_HELV); uiBlockSetButmFunc(block, do_editmode_undohistorymenu, NULL); diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 6773575ca84..b7923990101 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -86,7 +86,7 @@ void ED_undo_push(bContext *C, char *str) if (U.undosteps == 0) return; if(G.obedit->type==OB_MESH) - undo_push_mesh(str); + undo_push_mesh(C, str); else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) undo_push_curve(str); else if (G.obedit->type==OB_FONT) @@ -109,40 +109,45 @@ void ED_undo_push(bContext *C, char *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(); - } - -} - -static int ed_undo_exec(bContext *C, wmOperator *op) +static int ed_undo_step(bContext *C, wmOperator *op, int step) { 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); + undo_editmode_step(C, step); } else { + int do_glob_undo= 0; + if(G.f & G_TEXTUREPAINT) - undo_imagepaint_step(1); + undo_imagepaint_step(step); else if(sa->spacetype==SPACE_IMAGE) { SpaceImage *sima= (SpaceImage *)sa->spacedata.first; if(sima->flag & SI_DRAWTOOL) - undo_imagepaint_step(1); + undo_imagepaint_step(step); + else + do_glob_undo= 1; + } + else if(G.f & G_PARTICLEEDIT) { + if(step==1) + PE_undo(); else - undo_do(C); + PE_redo(); } - else if(G.f & G_PARTICLEEDIT) - PE_undo(); else { - undo_do(C); + do_glob_undo= 1; + } + + if(do_glob_undo) { + if(U.uiflag & USER_GLOBALUNDO) { +#ifndef DISABLE_PYTHON + // XXX BPY_scripts_clear_pyobjects(); +#endif + BKE_undo_step(C, step); + sound_initialize_sounds(); + } + } } @@ -151,39 +156,13 @@ static int ed_undo_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int ed_undo_exec(bContext *C, wmOperator *op) +{ + return ed_undo_step(C, op, 1); +} static int ed_redo_exec(bContext *C, wmOperator *op) { - 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 { - BKE_undo_step(C, -1); - sound_initialize_sounds(); - } - } - else if(G.f & G_PARTICLEEDIT) - PE_redo(); - else { - /* includes faceselect now */ - if(U.uiflag & USER_GLOBALUNDO) { - BKE_undo_step(C, -1); - sound_initialize_sounds(); - } - } - } - WM_event_add_notifier(C, NC_WINDOW, NULL); - return OPERATOR_FINISHED; - + return ed_undo_step(C, op, -1); } void ED_undo_menu(bContext *C) diff --git a/source/blender/editors/util/util_intern.h b/source/blender/editors/util/util_intern.h new file mode 100644 index 00000000000..37e6c5c25e1 --- /dev/null +++ b/source/blender/editors/util/util_intern.h @@ -0,0 +1,38 @@ +/** + * $Id: + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef ED_UTIL_INTERN_H +#define ED_UTIL_INTERN_H + +/* internal exports only */ + +/* editmode_undo.c */ +void undo_editmode_clear(void); + +#endif /* ED_UTIL_INTERN_H */ + |