Three functionalities in one commit, but there's overlap so I can't
separate it... 1) Curve/Surface editmode undo Uses same syntax as mesh undo, so simple to integrate. Edit-curve data is also quite simpler, so no need for any hack at all. It re-uses the undo system from next point, which is nice short & clean local code 2) Framework for global undo The undo calls themselves are commented out. In a next commit I want to enable it for a couple of main features, for further feedback. The speed goes surprisingly well, especially with this new version that 'pushes' undo after a command, ensuring interactivity isnt frustrated 3) framework for texture based icons in Blender Not activated code, but tested here. Part of 2.3 UI project. btw: Johnny Matthews will assist in (and complete) the undo project
This commit is contained in:
@@ -90,5 +90,9 @@ void clear_tilt(void);
|
|||||||
void clever_numbuts_curve(void);
|
void clever_numbuts_curve(void);
|
||||||
int bezt_compare (const void *e1, const void *e2);
|
int bezt_compare (const void *e1, const void *e2);
|
||||||
|
|
||||||
|
extern void undo_push_curve(char *name);
|
||||||
|
extern void undo_clear_curve(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* BDR_EDITCURVE_H */
|
#endif /* BDR_EDITCURVE_H */
|
||||||
|
|
||||||
|
|||||||
@@ -209,7 +209,8 @@ extern void ui_window_to_graphics(int win, float *x, float *y);
|
|||||||
/* interface_panel.c */
|
/* interface_panel.c */
|
||||||
extern void ui_draw_panel(uiBlock *block);
|
extern void ui_draw_panel(uiBlock *block);
|
||||||
extern void ui_do_panel(uiBlock *block, uiEvent *uevent);
|
extern void ui_do_panel(uiBlock *block, uiEvent *uevent);
|
||||||
extern void gl_round_box(float minx, float miny, float maxx, float maxy, float rad);
|
extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
|
||||||
|
extern void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shade);
|
||||||
|
|
||||||
/* interface_draw.c */
|
/* interface_draw.c */
|
||||||
extern void ui_set_embossfunc(uiBut *but, int drawtype);
|
extern void ui_set_embossfunc(uiBut *but, int drawtype);
|
||||||
|
|||||||
@@ -647,7 +647,7 @@ static void editing_panel_mesh_type(Object *ob, Mesh *me)
|
|||||||
if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
|
if( uiNewPanel(curarea, block, "Mesh", "Editing", 320, 0, 318, 204)==0) return;
|
||||||
|
|
||||||
uiBlockBeginAlign(block);
|
uiBlockBeginAlign(block);
|
||||||
uiDefButS(block, TOG|BIT|5, REDRAWVIEW3D, "Auto Smooth",10,180,154,19, &me->flag, 0, 0, 0, 0, "Treats all faces with angles less than Degr: as 'smooth' during render");
|
uiDefButS(block, TOG|BIT|5, REDRAWVIEW3D, "Auto Smooth",10,180,154,19, &me->flag, 0, 0, 0, 0, "Treats all set-smoothed faces with angles less than Degr: as 'smooth' during render");
|
||||||
uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
|
uiDefButS(block, NUM, B_DIFF, "Degr:", 10,160,154,19, &me->smoothresh, 1, 80, 0, 0, "Defines maximum angle between face normals that 'Auto Smooth' will operate on");
|
||||||
|
|
||||||
uiBlockBeginAlign(block);
|
uiBlockBeginAlign(block);
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
#include "DNA_scene_types.h"
|
#include "DNA_scene_types.h"
|
||||||
#include "DNA_screen_types.h"
|
#include "DNA_screen_types.h"
|
||||||
#include "DNA_view3d_types.h"
|
#include "DNA_view3d_types.h"
|
||||||
|
#include "DNA_userdef_types.h"
|
||||||
|
|
||||||
#include "BKE_utildefines.h"
|
#include "BKE_utildefines.h"
|
||||||
#include "BKE_library.h"
|
#include "BKE_library.h"
|
||||||
@@ -1043,6 +1044,8 @@ void switchdirectionNurb2(void)
|
|||||||
if(G.obedit->lay & G.vd->lay);
|
if(G.obedit->lay & G.vd->lay);
|
||||||
else return;
|
else return;
|
||||||
|
|
||||||
|
undo_push_curve("Switch direction");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if( isNurbsel(nu) ) switchdirectionNurb(nu);
|
if( isNurbsel(nu) ) switchdirectionNurb(nu);
|
||||||
@@ -1105,6 +1108,8 @@ void deselectall_nurb()
|
|||||||
|
|
||||||
if(G.obedit->lay & G.vd->lay);
|
if(G.obedit->lay & G.vd->lay);
|
||||||
else return;
|
else return;
|
||||||
|
|
||||||
|
undo_push_curve("Deselect all");
|
||||||
|
|
||||||
a= 0;
|
a= 0;
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
@@ -1194,6 +1199,8 @@ void hideNurb(int swap)
|
|||||||
|
|
||||||
if(G.obedit==0) return;
|
if(G.obedit==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Hide");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if((nu->type & 7)==CU_BEZIER) {
|
if((nu->type & 7)==CU_BEZIER) {
|
||||||
@@ -1249,6 +1256,8 @@ void revealNurb()
|
|||||||
|
|
||||||
if(G.obedit==0) return;
|
if(G.obedit==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Reveal");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
nu->hide= 0;
|
nu->hide= 0;
|
||||||
@@ -1293,6 +1302,8 @@ void selectswapNurb()
|
|||||||
|
|
||||||
if(G.obedit==0) return;
|
if(G.obedit==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Select swap");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if((nu->type & 7)==CU_BEZIER) {
|
if((nu->type & 7)==CU_BEZIER) {
|
||||||
@@ -1346,6 +1357,8 @@ void subdivideNurb()
|
|||||||
|
|
||||||
// printf("*** subdivideNurb: entering subdivide\n");
|
// printf("*** subdivideNurb: entering subdivide\n");
|
||||||
|
|
||||||
|
undo_push_curve("Subdivide");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
amount= 0;
|
amount= 0;
|
||||||
@@ -1868,6 +1881,8 @@ void setsplinetype(short type)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
undo_push_curve("Set spline type");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if(isNurbsel(nu)) {
|
if(isNurbsel(nu)) {
|
||||||
@@ -2248,6 +2263,8 @@ void merge_nurb()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
undo_push_curve("Merge");
|
||||||
|
|
||||||
nus1= nsortbase.first;
|
nus1= nsortbase.first;
|
||||||
nus2= nus1->next;
|
nus2= nus1->next;
|
||||||
|
|
||||||
@@ -2296,6 +2313,8 @@ void addsegment_nurb()
|
|||||||
float *fp, offset;
|
float *fp, offset;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
undo_push_curve("Add segment");
|
||||||
|
|
||||||
/* first decide if this is a surface merge! */
|
/* first decide if this is a surface merge! */
|
||||||
if(G.obedit->type==OB_SURF) nu= editNurb.first;
|
if(G.obedit->type==OB_SURF) nu= editNurb.first;
|
||||||
else nu= NULL;
|
else nu= NULL;
|
||||||
@@ -2450,6 +2469,8 @@ void mouse_nurb()
|
|||||||
BPoint *bp=0;
|
BPoint *bp=0;
|
||||||
short hand;
|
short hand;
|
||||||
|
|
||||||
|
undo_push_curve("Select");
|
||||||
|
|
||||||
hand= findnearestNurbvert(1, &nu, &bezt, &bp);
|
hand= findnearestNurbvert(1, &nu, &bezt, &bp);
|
||||||
|
|
||||||
if(bezt || bp) {
|
if(bezt || bp) {
|
||||||
@@ -2540,6 +2561,8 @@ void spinNurb(float *dvec, short mode)
|
|||||||
if(G.obedit==0 || G.obedit->type!=OB_SURF) return;
|
if(G.obedit==0 || G.obedit->type!=OB_SURF) return;
|
||||||
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
||||||
|
|
||||||
|
undo_push_curve("Spin");
|
||||||
|
|
||||||
Mat3CpyMat4(persmat, G.vd->viewmat);
|
Mat3CpyMat4(persmat, G.vd->viewmat);
|
||||||
Mat3Inv(persinv, persmat);
|
Mat3Inv(persinv, persmat);
|
||||||
|
|
||||||
@@ -2642,6 +2665,8 @@ void addvert_Nurb(int mode)
|
|||||||
|
|
||||||
if(mode=='e' && okee("Extrude")==0) return;
|
if(mode=='e' && okee("Extrude")==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Add vertex");
|
||||||
|
|
||||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||||
Mat3Inv(imat,mat);
|
Mat3Inv(imat,mat);
|
||||||
|
|
||||||
@@ -2759,6 +2784,21 @@ void addvert_Nurb(int mode)
|
|||||||
|
|
||||||
if(mode=='e') transform('d');
|
if(mode=='e') transform('d');
|
||||||
else while(get_mbut()&R_MOUSE) BIF_wait_for_statechange();
|
else while(get_mbut()&R_MOUSE) BIF_wait_for_statechange();
|
||||||
|
|
||||||
|
if(mode!='e') {
|
||||||
|
/* dependencies with other objects, should become event */
|
||||||
|
Base *base= FIRSTBASE;
|
||||||
|
while(base) {
|
||||||
|
if(base->lay & G.vd->lay) {
|
||||||
|
if(base->object->type==OB_CURVE) {
|
||||||
|
Curve *cu= base->object->data;
|
||||||
|
if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
|
||||||
|
makeDispList(base->object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base= base->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void extrude_nurb()
|
void extrude_nurb()
|
||||||
@@ -2780,6 +2820,8 @@ void extrude_nurb()
|
|||||||
else {
|
else {
|
||||||
|
|
||||||
if(okee("Extrude")==0) return;
|
if(okee("Extrude")==0) return;
|
||||||
|
undo_push_curve("Extrude");
|
||||||
|
|
||||||
ok= extrudeflagNurb(1); /* '1'= flag */
|
ok= extrudeflagNurb(1); /* '1'= flag */
|
||||||
|
|
||||||
if(ok) {
|
if(ok) {
|
||||||
@@ -2801,6 +2843,8 @@ void makecyclicNurb()
|
|||||||
float *fp;
|
float *fp;
|
||||||
int a, b, cyclmode=0;
|
int a, b, cyclmode=0;
|
||||||
|
|
||||||
|
undo_push_curve("Cyclic");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if( nu->pntsu>1 || nu->pntsv>1) {
|
if( nu->pntsu>1 || nu->pntsv>1) {
|
||||||
@@ -2906,6 +2950,8 @@ void selectconnected_nurb()
|
|||||||
BPoint *bp;
|
BPoint *bp;
|
||||||
int a;
|
int a;
|
||||||
|
|
||||||
|
undo_push_curve("Select connected");
|
||||||
|
|
||||||
findnearestNurbvert(1, &nu, &bezt, &bp);
|
findnearestNurbvert(1, &nu, &bezt, &bp);
|
||||||
if(bezt) {
|
if(bezt) {
|
||||||
a= nu->pntsu;
|
a= nu->pntsu;
|
||||||
@@ -2958,6 +3004,8 @@ void selectrow_nurb()
|
|||||||
if(G.obedit==NULL || G.obedit->type!=OB_SURF) return;
|
if(G.obedit==NULL || G.obedit->type!=OB_SURF) return;
|
||||||
if(lastselbp==NULL) return;
|
if(lastselbp==NULL) return;
|
||||||
|
|
||||||
|
undo_push_curve("Select Row");
|
||||||
|
|
||||||
/* find the correct nurb and toggle with u of v */
|
/* find the correct nurb and toggle with u of v */
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
@@ -3004,6 +3052,8 @@ void adduplicate_nurb()
|
|||||||
|
|
||||||
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
||||||
|
|
||||||
|
undo_push_curve("Duplicate");
|
||||||
|
|
||||||
adduplicateflagNurb(1);
|
adduplicateflagNurb(1);
|
||||||
|
|
||||||
countall();
|
countall();
|
||||||
@@ -3026,6 +3076,8 @@ void delNurb()
|
|||||||
|
|
||||||
if(event== -1) return;
|
if(event== -1) return;
|
||||||
|
|
||||||
|
undo_push_curve("Delete");
|
||||||
|
|
||||||
if(G.obedit->type==OB_SURF) {
|
if(G.obedit->type==OB_SURF) {
|
||||||
if(event==0) deleteflagNurb(1);
|
if(event==0) deleteflagNurb(1);
|
||||||
else freeNurblist(&editNurb);
|
else freeNurblist(&editNurb);
|
||||||
@@ -3302,6 +3354,8 @@ void join_curve(int type)
|
|||||||
}
|
}
|
||||||
else if(okee("Join selected curves")==0) return;
|
else if(okee("Join selected curves")==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Join");
|
||||||
|
|
||||||
/* trasnform all selected curves inverse in obact */
|
/* trasnform all selected curves inverse in obact */
|
||||||
Mat4Invert(imat, ob->obmat);
|
Mat4Invert(imat, ob->obmat);
|
||||||
|
|
||||||
@@ -3813,7 +3867,10 @@ void add_primitiveCurve(int stype)
|
|||||||
default_curve_ipo(cu);
|
default_curve_ipo(cu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else cu= G.obedit->data;
|
else {
|
||||||
|
cu= G.obedit->data;
|
||||||
|
undo_push_curve("Add primitive");
|
||||||
|
}
|
||||||
|
|
||||||
if(cu->flag & CU_3D) type &= ~CU_2D;
|
if(cu->flag & CU_3D) type &= ~CU_2D;
|
||||||
|
|
||||||
@@ -3850,6 +3907,9 @@ void add_primitiveNurb(int type)
|
|||||||
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
|
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
|
||||||
newname= 1;
|
newname= 1;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
undo_push_curve("Add primitive");
|
||||||
|
}
|
||||||
|
|
||||||
nu= addNurbprim(4, type, newname);
|
nu= addNurbprim(4, type, newname);
|
||||||
BLI_addtail(&editNurb,nu);
|
BLI_addtail(&editNurb,nu);
|
||||||
@@ -3870,6 +3930,8 @@ void clear_tilt()
|
|||||||
|
|
||||||
if(okee("Clear tilt")==0) return;
|
if(okee("Clear tilt")==0) return;
|
||||||
|
|
||||||
|
undo_push_curve("Clear tilt");
|
||||||
|
|
||||||
nu= editNurb.first;
|
nu= editNurb.first;
|
||||||
while(nu) {
|
while(nu) {
|
||||||
if( nu->bezt ) {
|
if( nu->bezt ) {
|
||||||
@@ -3895,70 +3957,6 @@ void clear_tilt()
|
|||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clever_numbuts_curve()
|
|
||||||
{
|
|
||||||
BPoint *bp;
|
|
||||||
BezTriple *bezt;
|
|
||||||
float old[3], delta[3];
|
|
||||||
int a;
|
|
||||||
|
|
||||||
if(lastnu==NULL) return;
|
|
||||||
if(lastnu->bp) {
|
|
||||||
bp= lastnu->bp;
|
|
||||||
a= lastnu->pntsu*lastnu->pntsv;
|
|
||||||
while(a--) {
|
|
||||||
if(bp->f1 & 1) break;
|
|
||||||
bp++;
|
|
||||||
}
|
|
||||||
if(bp==0) return;
|
|
||||||
|
|
||||||
add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bp->vec, 0);
|
|
||||||
add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bp->vec+1, 0);
|
|
||||||
add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bp->vec+2, 0);
|
|
||||||
add_numbut(3, NUM|FLO, " W:", 0.0, 100.0, bp->vec+3, 0);
|
|
||||||
|
|
||||||
do_clever_numbuts("Active BPoint", 4, REDRAW);
|
|
||||||
makeDispList(G.obedit);
|
|
||||||
}
|
|
||||||
else if(lastnu->bezt) {
|
|
||||||
bezt= lastnu->bezt;
|
|
||||||
a= lastnu->pntsu;
|
|
||||||
while(a--) {
|
|
||||||
if(BEZSELECTED(bezt)) break;
|
|
||||||
bezt++;
|
|
||||||
}
|
|
||||||
if(bezt==0) return;
|
|
||||||
|
|
||||||
if(bezt->f2 & 1) {
|
|
||||||
add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[1], 0);
|
|
||||||
add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[1]+1, 0);
|
|
||||||
add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[1]+2, 0);
|
|
||||||
VECCOPY(old, bezt->vec[1]);
|
|
||||||
do_clever_numbuts("Active Bezier Point", 3, REDRAW);
|
|
||||||
|
|
||||||
VecSubf(delta, bezt->vec[1], old);
|
|
||||||
VecAddf(bezt->vec[0], bezt->vec[0], delta);
|
|
||||||
VecAddf(bezt->vec[2], bezt->vec[2], delta);
|
|
||||||
makeDispList(G.obedit);
|
|
||||||
}
|
|
||||||
else if(bezt->f1 & 1) {
|
|
||||||
add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[0], 0);
|
|
||||||
add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[0]+1, 0);
|
|
||||||
add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[0]+2, 0);
|
|
||||||
|
|
||||||
do_clever_numbuts("Active Handle Point", 3, REDRAW);
|
|
||||||
}
|
|
||||||
else if(bezt->f3 & 1) {
|
|
||||||
add_numbut(0, NUM|FLO, "LocX:", -G.vd->far, G.vd->far, bezt->vec[2], 0);
|
|
||||||
add_numbut(1, NUM|FLO, "LocY:", -G.vd->far, G.vd->far, bezt->vec[2]+1, 0);
|
|
||||||
add_numbut(2, NUM|FLO, "LocZ:", -G.vd->far, G.vd->far, bezt->vec[2]+2, 0);
|
|
||||||
|
|
||||||
do_clever_numbuts("Active Handle Point", 3, REDRAW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
int bezt_compare (const void *e1, const void *e2)
|
int bezt_compare (const void *e1, const void *e2)
|
||||||
{
|
{
|
||||||
BezTriple *b1 = *((BezTriple**)e1);
|
BezTriple *b1 = *((BezTriple**)e1);
|
||||||
@@ -3982,3 +3980,165 @@ int bezt_compare (const void *e1, const void *e2)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* **************** undo for curves ************** */
|
||||||
|
|
||||||
|
#define MAXUNDONAME 64
|
||||||
|
typedef struct UndoElem {
|
||||||
|
struct UndoElem *next, *prev;
|
||||||
|
Object *ob;
|
||||||
|
ListBase editnurb;
|
||||||
|
char name[MAXUNDONAME];
|
||||||
|
} UndoElem;
|
||||||
|
|
||||||
|
static ListBase undobase={NULL, NULL};
|
||||||
|
static UndoElem *curundo= NULL;
|
||||||
|
|
||||||
|
static void undo_restore(UndoElem *undo)
|
||||||
|
{
|
||||||
|
Nurb *nu, *newnu;
|
||||||
|
|
||||||
|
freeNurblist(&editNurb);
|
||||||
|
|
||||||
|
/* copy */
|
||||||
|
nu= undo->editnurb.first;
|
||||||
|
while(nu) {
|
||||||
|
newnu= duplicateNurb(nu);
|
||||||
|
BLI_addtail(&editNurb, newnu);
|
||||||
|
nu= nu->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* name can be a dynamic string */
|
||||||
|
void undo_push_curve(char *name)
|
||||||
|
{
|
||||||
|
Nurb *nu, *newnu;
|
||||||
|
UndoElem *uel;
|
||||||
|
int nr;
|
||||||
|
|
||||||
|
/* remove all undos after (also when curundo==NULL) */
|
||||||
|
while(undobase.last != curundo) {
|
||||||
|
uel= undobase.last;
|
||||||
|
BLI_remlink(&undobase, uel);
|
||||||
|
freeNurblist(&uel->editnurb);
|
||||||
|
MEM_freeN(uel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make new */
|
||||||
|
curundo= uel= MEM_callocN(sizeof(UndoElem), "undo curve");
|
||||||
|
strncpy(uel->name, name, MAXUNDONAME-1);
|
||||||
|
BLI_addtail(&undobase, uel);
|
||||||
|
|
||||||
|
/* and limit amount to the maximum */
|
||||||
|
nr= 0;
|
||||||
|
uel= undobase.last;
|
||||||
|
while(uel) {
|
||||||
|
nr++;
|
||||||
|
if(nr==U.undosteps) break;
|
||||||
|
uel= uel->prev;
|
||||||
|
}
|
||||||
|
if(uel) {
|
||||||
|
while(undobase.first!=uel) {
|
||||||
|
UndoElem *first= undobase.first;
|
||||||
|
BLI_remlink(&undobase, first);
|
||||||
|
freeNurblist(&first->editnurb);
|
||||||
|
MEM_freeN(first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy editNurb */
|
||||||
|
nu= editNurb.first;
|
||||||
|
while(nu) {
|
||||||
|
newnu= duplicateNurb(nu);
|
||||||
|
BLI_addtail(&curundo->editnurb, newnu);
|
||||||
|
nu= nu->next;
|
||||||
|
}
|
||||||
|
curundo->ob= G.obedit;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at previous step */
|
||||||
|
void undo_curve_step(int step)
|
||||||
|
{
|
||||||
|
Base *base;
|
||||||
|
UndoElem *uel, *next;
|
||||||
|
|
||||||
|
/* prevent undo to happen on wrong object */
|
||||||
|
uel= undobase.first;
|
||||||
|
while(uel) {
|
||||||
|
next= uel->next;
|
||||||
|
if(uel->ob!=G.obedit) {
|
||||||
|
if(uel==curundo) curundo= next;
|
||||||
|
BLI_remlink(&undobase, uel);
|
||||||
|
freeNurblist(&uel->editnurb);
|
||||||
|
MEM_freeN(uel);
|
||||||
|
}
|
||||||
|
uel= next;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(step==1) {
|
||||||
|
if(curundo==NULL) error("No undo available");
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* if we undo, the current situation needs saved */
|
||||||
|
if(curundo->next==NULL) {
|
||||||
|
undo_push_curve("Original");
|
||||||
|
curundo= curundo->prev;
|
||||||
|
}
|
||||||
|
undo_restore(curundo);
|
||||||
|
curundo= curundo->prev;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
UndoElem *redo;
|
||||||
|
|
||||||
|
/* curundo has to remain the undo step, so we load curundo->next->next! */
|
||||||
|
|
||||||
|
if(curundo==NULL) redo= undobase.first;
|
||||||
|
else redo= curundo->next;
|
||||||
|
|
||||||
|
if(redo==NULL || redo->next==NULL) error("No redo available");
|
||||||
|
else {
|
||||||
|
undo_restore(redo->next);
|
||||||
|
curundo= redo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastnu= NULL; /* for selected */
|
||||||
|
|
||||||
|
makeDispList(G.obedit);
|
||||||
|
|
||||||
|
/* dependencies with other objects */
|
||||||
|
base= FIRSTBASE;
|
||||||
|
while(base) {
|
||||||
|
if(base->lay & G.vd->lay) {
|
||||||
|
if(base->object->type==OB_CURVE) {
|
||||||
|
Curve *cu= base->object->data;
|
||||||
|
if(G.obedit==cu->bevobj || G.obedit==cu->taperobj)
|
||||||
|
makeDispList(base->object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
base= base->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
countall();
|
||||||
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
|
allqueue(REDRAWBUTSEDIT, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void undo_clear_curve(void)
|
||||||
|
{
|
||||||
|
UndoElem *uel;
|
||||||
|
|
||||||
|
uel= undobase.first;
|
||||||
|
while(uel) {
|
||||||
|
freeNurblist(&uel->editnurb);
|
||||||
|
uel= uel->next;
|
||||||
|
}
|
||||||
|
BLI_freelistN(&undobase);
|
||||||
|
curundo= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***/
|
||||||
|
|||||||
@@ -4576,8 +4576,11 @@ void transform(int mode)
|
|||||||
}
|
}
|
||||||
if(mode=='w' && G.obedit==0) return;
|
if(mode=='w' && G.obedit==0) return;
|
||||||
|
|
||||||
if (G.obedit && G.obedit->type == OB_MESH) {
|
if (G.obedit) {
|
||||||
undo_push_mesh(transform_mode_to_string(mode));
|
if(G.obedit->type == OB_MESH)
|
||||||
|
undo_push_mesh(transform_mode_to_string(mode));
|
||||||
|
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||||
|
undo_push_curve(transform_mode_to_string(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* what data will be involved? */
|
/* what data will be involved? */
|
||||||
@@ -7424,6 +7427,8 @@ void mirror_edit(short mode) {
|
|||||||
TransVert *tv;
|
TransVert *tv;
|
||||||
|
|
||||||
if(G.obedit->type==OB_MESH) undo_push_mesh("Mirror"); /* If it's a mesh, push it down the undo pipe */
|
if(G.obedit->type==OB_MESH) undo_push_mesh("Mirror"); /* If it's a mesh, push it down the undo pipe */
|
||||||
|
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||||
|
undo_push_curve("Mirror");
|
||||||
|
|
||||||
make_trans_verts(min, max, 0);
|
make_trans_verts(min, max, 0);
|
||||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||||
|
|||||||
@@ -1796,6 +1796,7 @@ static int ui_do_but_NUMSLI(uiBut *but)
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uiActAsTextBut(but);
|
uiActAsTextBut(but);
|
||||||
|
uibut_do_func(but); // this is done in ui_do_but_SLI() not in uiActAsTextBut()
|
||||||
}
|
}
|
||||||
|
|
||||||
while(get_mbut() & L_MOUSE) BIF_wait_for_statechange();
|
while(get_mbut() & L_MOUSE) BIF_wait_for_statechange();
|
||||||
@@ -3090,6 +3091,8 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
|
|||||||
if(inside || uevent->event!=LEFTMOUSE) {
|
if(inside || uevent->event!=LEFTMOUSE) {
|
||||||
butevent= ui_do_button(block, but, uevent);
|
butevent= ui_do_button(block, but, uevent);
|
||||||
|
|
||||||
|
// if(but->type!=BLOCK) BIF_write_undo(but->str);
|
||||||
|
|
||||||
if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
|
if(butevent) addqueue(block->winq, UI_BUT_EVENT, (short)butevent);
|
||||||
|
|
||||||
/* i doubt about the next line! */
|
/* i doubt about the next line! */
|
||||||
@@ -3198,15 +3201,13 @@ static uiSaveUnder *ui_draw_but_tip(uiBut *but)
|
|||||||
|
|
||||||
glColor4ub(0, 0, 0, 20);
|
glColor4ub(0, 0, 0, 20);
|
||||||
|
|
||||||
glBegin(GL_POLYGON);
|
gl_round_box(GL_POLYGON, x1+3, y1-1, x2+1, y2-2, 2.0);
|
||||||
gl_round_box(x1+3, y1-1, x2+1, y2-2, 2.0);
|
gl_round_box(GL_POLYGON, x1+3, y1-2, x2+2, y2-2, 3.0);
|
||||||
gl_round_box(x1+3, y1-2, x2+2, y2-2, 3.0);
|
|
||||||
|
|
||||||
glColor4ub(0, 0, 0, 8);
|
glColor4ub(0, 0, 0, 8);
|
||||||
|
|
||||||
gl_round_box(x1+3, y1-3, x2+3, y2-3, 4.0);
|
gl_round_box(GL_POLYGON, x1+3, y1-3, x2+3, y2-3, 4.0);
|
||||||
gl_round_box(x1+3, y1-4, x2+4, y2-3, 5.0);
|
gl_round_box(GL_POLYGON, x1+3, y1-4, x2+4, y2-3, 5.0);
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
|
|||||||
@@ -120,9 +120,13 @@ void uiEmboss(float x1, float y1, float x2, float y2, int sel)
|
|||||||
|
|
||||||
static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
||||||
{
|
{
|
||||||
|
void BIF_icon_pos(float xs, float ys);
|
||||||
int blend= 0;
|
int blend= 0;
|
||||||
float xs=0, ys=0;
|
float xs=0, ys=0;
|
||||||
|
|
||||||
|
// this icon doesn't need draw...
|
||||||
|
if(icon==ICON_BLANK1) return;
|
||||||
|
|
||||||
if(but->flag & UI_ICON_LEFT) {
|
if(but->flag & UI_ICON_LEFT) {
|
||||||
if (but->type==BUTM) {
|
if (but->type==BUTM) {
|
||||||
xs= but->x1+1.0;
|
xs= but->x1+1.0;
|
||||||
@@ -145,6 +149,7 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
|||||||
}
|
}
|
||||||
|
|
||||||
glRasterPos2f(xs, ys);
|
glRasterPos2f(xs, ys);
|
||||||
|
// BIF_icon_pos(xs, ys);
|
||||||
|
|
||||||
if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
|
if(but->aspect>1.1) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
|
||||||
else if(but->aspect<0.9) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
|
else if(but->aspect<0.9) glPixelZoom(1.0/but->aspect, 1.0/but->aspect);
|
||||||
@@ -160,24 +165,6 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
|||||||
}
|
}
|
||||||
BIF_draw_icon_blended(icon, but->themecol, blend);
|
BIF_draw_icon_blended(icon, but->themecol, blend);
|
||||||
|
|
||||||
/* old blending method... hrums */
|
|
||||||
/* if(but->flag & UI_SELECT) {
|
|
||||||
if(but->flag & UI_ACTIVE) {
|
|
||||||
BIF_draw_icon_blended(icon, but->themecol, -80);
|
|
||||||
} else {
|
|
||||||
BIF_draw_icon_blended(icon, but->themecol, -45);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ((but->flag & UI_ACTIVE) && but->type==BUTM) {
|
|
||||||
BIF_draw_icon_blended(icon, but->themecol, 0);
|
|
||||||
} else if (but->flag & UI_ACTIVE) {
|
|
||||||
BIF_draw_icon_blended(icon, but->themecol, 25);
|
|
||||||
} else {
|
|
||||||
BIF_draw_icon_blended(icon, but->themecol, 45);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
glBlendFunc(GL_ONE, GL_ZERO);
|
glBlendFunc(GL_ONE, GL_ZERO);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
|
||||||
@@ -338,9 +325,7 @@ static void shaded_button(float x1, float y1, float x2, float y2, float asp, int
|
|||||||
fdrawline(x1, y1, x2, y1);
|
fdrawline(x1, y1, x2, y1);
|
||||||
} else {
|
} else {
|
||||||
MM_DARK;
|
MM_DARK;
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
|
||||||
gl_round_box(x1, y1, x2, y2, 1.5);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
/* END OUTER OUTLINE */
|
/* END OUTER OUTLINE */
|
||||||
}
|
}
|
||||||
@@ -381,9 +366,7 @@ static void flat_button(float x1, float y1, float x2, float y2, float asp, int c
|
|||||||
fdrawline(x1, y1, x2, y1);
|
fdrawline(x1, y1, x2, y1);
|
||||||
} else {
|
} else {
|
||||||
MM_DARK;
|
MM_DARK;
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
|
||||||
gl_round_box(x1, y1, x2, y2, 1.5);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
/* END OUTER OUTLINE */
|
/* END OUTER OUTLINE */
|
||||||
}
|
}
|
||||||
@@ -1049,15 +1032,14 @@ static void round_button(float x1, float y1, float x2, float y2, float asp, int
|
|||||||
rad= (y2-y1)/2.0;
|
rad= (y2-y1)/2.0;
|
||||||
if(rad>7.0) rad= 7.0;
|
if(rad>7.0) rad= 7.0;
|
||||||
|
|
||||||
glBegin(GL_POLYGON);
|
/* the shaded round_box version (0.1 is shade factor) */
|
||||||
gl_round_box(x1, y1, x2, y2, rad);
|
//gl_round_box_shade(GL_POLYGON, x1, y1, x2, y2, rad, 0.1);
|
||||||
glEnd();
|
|
||||||
|
|
||||||
|
gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
|
||||||
|
|
||||||
BIF_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
|
BIF_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad);
|
||||||
gl_round_box(x1, y1, x2, y2, rad);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* button in midst of alignment row */
|
/* button in midst of alignment row */
|
||||||
@@ -1161,10 +1143,8 @@ static void ui_draw_round(int type, int colorid, float asp, float x1, float y1,
|
|||||||
if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
|
if(flag & UI_ACTIVE) BIF_ThemeColorShade(colorid, 0);
|
||||||
else BIF_ThemeColorShade(colorid, -10);
|
else BIF_ThemeColorShade(colorid, -10);
|
||||||
// assuming its not inside alignment...
|
// assuming its not inside alignment...
|
||||||
uiSetRoundBox(6);
|
uiSetRoundBox(round_align_fix);
|
||||||
glBegin(GL_POLYGON);
|
gl_round_box(GL_POLYGON, x2-9, y1+asp, x2-asp, y2-asp, 7.0);
|
||||||
gl_round_box(x2-9, y1+asp, x2-asp, y2-asp, 7.0);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
BIF_ThemeColorShade(colorid, -60);
|
BIF_ThemeColorShade(colorid, -60);
|
||||||
ui_default_iconrow_arrows(x1, y1, x2, y2);
|
ui_default_iconrow_arrows(x1, y1, x2, y2);
|
||||||
@@ -1176,9 +1156,7 @@ static void ui_draw_round(int type, int colorid, float asp, float x1, float y1,
|
|||||||
// assuming its not inside alignment...
|
// assuming its not inside alignment...
|
||||||
if(x2-x1 > 24) {
|
if(x2-x1 > 24) {
|
||||||
uiSetRoundBox(round_align_fix);
|
uiSetRoundBox(round_align_fix);
|
||||||
glBegin(GL_POLYGON);
|
gl_round_box(GL_POLYGON, x2-16, y1+asp, x2-asp, y2-asp, 7.0);
|
||||||
gl_round_box(x2-16, y1+asp, x2-asp, y2-asp, 7.0);
|
|
||||||
glEnd();
|
|
||||||
}
|
}
|
||||||
BIF_ThemeColorShade(colorid, -60);
|
BIF_ThemeColorShade(colorid, -60);
|
||||||
ui_default_menu_arrows(x1, y1, x2, y2);
|
ui_default_menu_arrows(x1, y1, x2, y2);
|
||||||
|
|||||||
@@ -114,7 +114,181 @@ void uiSetRoundBox(int type)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gl_round_box_topshade(float minx, float miny, float maxx, float maxy, float rad)
|
void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad)
|
||||||
|
{
|
||||||
|
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
|
||||||
|
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
|
||||||
|
int a;
|
||||||
|
|
||||||
|
/* mult */
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
vec[a][0]*= rad; vec[a][1]*= rad;
|
||||||
|
}
|
||||||
|
|
||||||
|
glBegin(mode);
|
||||||
|
|
||||||
|
/* start with corner right-bottom */
|
||||||
|
if(roundboxtype & 4) {
|
||||||
|
glVertex2f( maxx-rad, miny);
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
|
||||||
|
}
|
||||||
|
glVertex2f( maxx, miny+rad);
|
||||||
|
}
|
||||||
|
else glVertex2f( maxx, miny);
|
||||||
|
|
||||||
|
/* corner right-top */
|
||||||
|
if(roundboxtype & 2) {
|
||||||
|
glVertex2f( maxx, maxy-rad);
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
|
||||||
|
}
|
||||||
|
glVertex2f( maxx-rad, maxy);
|
||||||
|
}
|
||||||
|
else glVertex2f( maxx, maxy);
|
||||||
|
|
||||||
|
/* corner left-top */
|
||||||
|
if(roundboxtype & 1) {
|
||||||
|
glVertex2f( minx+rad, maxy);
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
|
||||||
|
}
|
||||||
|
glVertex2f( minx, maxy-rad);
|
||||||
|
}
|
||||||
|
else glVertex2f( minx, maxy);
|
||||||
|
|
||||||
|
/* corner left-bottom */
|
||||||
|
if(roundboxtype & 8) {
|
||||||
|
glVertex2f( minx, miny+rad);
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
|
||||||
|
}
|
||||||
|
glVertex2f( minx+rad, miny);
|
||||||
|
}
|
||||||
|
else glVertex2f( minx, miny);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void round_box_shade_col(float *col1, float *col2, float fac)
|
||||||
|
{
|
||||||
|
float col[3];
|
||||||
|
|
||||||
|
col[0]= (fac*col1[0] + (1.0-fac)*col2[0]);
|
||||||
|
col[1]= (fac*col1[1] + (1.0-fac)*col2[1]);
|
||||||
|
col[2]= (fac*col1[2] + (1.0-fac)*col2[2]);
|
||||||
|
|
||||||
|
glColor3fv(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* linear horizontal shade within button or in outline */
|
||||||
|
void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shade)
|
||||||
|
{
|
||||||
|
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
|
||||||
|
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
|
||||||
|
float div= maxy-miny;
|
||||||
|
float coltop[3], coldown[3], color[4];
|
||||||
|
int a;
|
||||||
|
|
||||||
|
/* mult */
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
vec[a][0]*= rad; vec[a][1]*= rad;
|
||||||
|
}
|
||||||
|
/* get current color, needs to be outside of glBegin/End */
|
||||||
|
glGetFloatv(GL_CURRENT_COLOR, color);
|
||||||
|
|
||||||
|
/* 'shade' defines strength of shading */
|
||||||
|
coltop[0]= color[0]+shade; if(coltop[0]>1.0) coltop[0]= 1.0;
|
||||||
|
coltop[1]= color[1]+shade; if(coltop[1]>1.0) coltop[1]= 1.0;
|
||||||
|
coltop[2]= color[2]+shade; if(coltop[2]>1.0) coltop[2]= 1.0;
|
||||||
|
coldown[0]= color[0]-shade; if(coldown[0]<0.0) coldown[0]= 0.0;
|
||||||
|
coldown[1]= color[1]-shade; if(coldown[1]<0.0) coldown[1]= 0.0;
|
||||||
|
coldown[2]= color[2]-shade; if(coldown[2]<0.0) coldown[2]= 0.0;
|
||||||
|
|
||||||
|
glShadeModel(GL_SMOOTH);
|
||||||
|
glBegin(mode);
|
||||||
|
|
||||||
|
/* start with corner right-bottom */
|
||||||
|
if(roundboxtype & 4) {
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, 0.0);
|
||||||
|
glVertex2f( maxx-rad, miny);
|
||||||
|
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
round_box_shade_col(coltop, coldown, vec[a][1]/div);
|
||||||
|
glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, rad/div);
|
||||||
|
glVertex2f( maxx, miny+rad);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
round_box_shade_col(coltop, coldown, 0.0);
|
||||||
|
glVertex2f( maxx, miny);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* corner right-top */
|
||||||
|
if(roundboxtype & 2) {
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, (div-rad)/div);
|
||||||
|
glVertex2f( maxx, maxy-rad);
|
||||||
|
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div);
|
||||||
|
glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][1]);
|
||||||
|
}
|
||||||
|
round_box_shade_col(coltop, coldown, 1.0);
|
||||||
|
glVertex2f( maxx-rad, maxy);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
round_box_shade_col(coltop, coldown, 1.0);
|
||||||
|
glVertex2f( maxx, maxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* corner left-top */
|
||||||
|
if(roundboxtype & 1) {
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, 1.0);
|
||||||
|
glVertex2f( minx+rad, maxy);
|
||||||
|
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
round_box_shade_col(coltop, coldown, (div-vec[a][1])/div);
|
||||||
|
glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, (div-rad)/div);
|
||||||
|
glVertex2f( minx, maxy-rad);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
round_box_shade_col(coltop, coldown, 1.0);
|
||||||
|
glVertex2f( minx, maxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* corner left-bottom */
|
||||||
|
if(roundboxtype & 8) {
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, rad/div);
|
||||||
|
glVertex2f( minx, miny+rad);
|
||||||
|
|
||||||
|
for(a=0; a<7; a++) {
|
||||||
|
round_box_shade_col(coltop, coldown, (rad-vec[a][1])/div);
|
||||||
|
glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
round_box_shade_col(coltop, coldown, 0.0);
|
||||||
|
glVertex2f( minx+rad, miny);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
round_box_shade_col(coltop, coldown, 0.0);
|
||||||
|
glVertex2f( minx, miny);
|
||||||
|
}
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
glShadeModel(GL_FLAT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* only for headers */
|
||||||
|
static void gl_round_box_topshade(float minx, float miny, float maxx, float maxy, float rad)
|
||||||
{
|
{
|
||||||
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
|
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
|
||||||
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
|
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
|
||||||
@@ -161,60 +335,6 @@ void gl_round_box_topshade(float minx, float miny, float maxx, float maxy, float
|
|||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void gl_round_box(float minx, float miny, float maxx, float maxy, float rad)
|
|
||||||
{
|
|
||||||
float vec[7][2]= {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293},
|
|
||||||
{0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}};
|
|
||||||
int a;
|
|
||||||
|
|
||||||
/* mult */
|
|
||||||
for(a=0; a<7; a++) {
|
|
||||||
vec[a][0]*= rad; vec[a][1]*= rad;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* start with corner right-bottom */
|
|
||||||
if(roundboxtype & 4) {
|
|
||||||
glVertex2f( maxx-rad, miny);
|
|
||||||
for(a=0; a<7; a++) {
|
|
||||||
glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
|
|
||||||
}
|
|
||||||
glVertex2f( maxx, miny+rad);
|
|
||||||
}
|
|
||||||
else glVertex2f( maxx, miny);
|
|
||||||
|
|
||||||
/* corner right-top */
|
|
||||||
if(roundboxtype & 2) {
|
|
||||||
glVertex2f( maxx, maxy-rad);
|
|
||||||
for(a=0; a<7; a++) {
|
|
||||||
glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
|
|
||||||
}
|
|
||||||
glVertex2f( maxx-rad, maxy);
|
|
||||||
}
|
|
||||||
else glVertex2f( maxx, maxy);
|
|
||||||
|
|
||||||
/* corner left-top */
|
|
||||||
if(roundboxtype & 1) {
|
|
||||||
glVertex2f( minx+rad, maxy);
|
|
||||||
for(a=0; a<7; a++) {
|
|
||||||
glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
|
|
||||||
}
|
|
||||||
glVertex2f( minx, maxy-rad);
|
|
||||||
}
|
|
||||||
else glVertex2f( minx, maxy);
|
|
||||||
|
|
||||||
/* corner left-bottom */
|
|
||||||
if(roundboxtype & 8) {
|
|
||||||
glVertex2f( minx, miny+rad);
|
|
||||||
for(a=0; a<7; a++) {
|
|
||||||
glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
|
|
||||||
}
|
|
||||||
glVertex2f( minx+rad, miny);
|
|
||||||
}
|
|
||||||
else glVertex2f( minx, miny);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* for headers and floating panels */
|
/* for headers and floating panels */
|
||||||
void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad)
|
void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad)
|
||||||
{
|
{
|
||||||
@@ -229,9 +349,7 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* solid part */
|
/* solid part */
|
||||||
glBegin(GL_POLYGON);
|
gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
|
||||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* set antialias line */
|
/* set antialias line */
|
||||||
glEnable( GL_LINE_SMOOTH );
|
glEnable( GL_LINE_SMOOTH );
|
||||||
@@ -243,9 +361,7 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad)
|
|||||||
|
|
||||||
/* total outline */
|
/* total outline */
|
||||||
if(roundboxtype & UI_RB_ALPHA) glColor4ub(0,0,0, 128); else glColor4ub(0,0,0, 255);
|
if(roundboxtype & UI_RB_ALPHA) glColor4ub(0,0,0, 128); else glColor4ub(0,0,0, 255);
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glDisable( GL_LINE_SMOOTH );
|
glDisable( GL_LINE_SMOOTH );
|
||||||
|
|
||||||
@@ -276,9 +392,7 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
|
|||||||
glEnable( GL_BLEND );
|
glEnable( GL_BLEND );
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glDisable( GL_BLEND );
|
glDisable( GL_BLEND );
|
||||||
glDisable( GL_LINE_SMOOTH );
|
glDisable( GL_LINE_SMOOTH );
|
||||||
@@ -300,18 +414,14 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* solid part */
|
/* solid part */
|
||||||
glBegin(GL_POLYGON);
|
gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
|
||||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
/* set antialias line */
|
/* set antialias line */
|
||||||
glEnable( GL_LINE_SMOOTH );
|
glEnable( GL_LINE_SMOOTH );
|
||||||
glEnable( GL_BLEND );
|
glEnable( GL_BLEND );
|
||||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||||
|
|
||||||
glBegin(GL_LINE_LOOP);
|
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
|
||||||
glEnd();
|
|
||||||
|
|
||||||
glDisable( GL_BLEND );
|
glDisable( GL_BLEND );
|
||||||
glDisable( GL_LINE_SMOOTH );
|
glDisable( GL_LINE_SMOOTH );
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $Id$
|
* $Id$
|
||||||
*
|
*
|
||||||
@@ -67,86 +65,97 @@ static int theme_spacetype= SPACE_VIEW3D;
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char *data;
|
unsigned char *data;
|
||||||
|
float uv[4][2];
|
||||||
|
GLuint texid;
|
||||||
int w, h;
|
int w, h;
|
||||||
} Icon;
|
} Icon;
|
||||||
|
|
||||||
|
|
||||||
static Icon *icon_from_data(unsigned char *rect, int w, int h, int rowstride)
|
static Icon *icon_from_data(unsigned char *rect, GLuint texid, int xofs, int yofs, int w, int h, int rowstride)
|
||||||
{
|
{
|
||||||
Icon *icon= MEM_mallocN(sizeof(*icon), "internicon");
|
Icon *icon= MEM_mallocN(sizeof(*icon), "internicon");
|
||||||
int y;
|
int y;
|
||||||
icon->data= MEM_mallocN(w*h*4, "icon->data");
|
|
||||||
|
icon->texid= texid;
|
||||||
|
icon->uv[0][0]= ((float)xofs)/512.0;
|
||||||
|
icon->uv[0][1]= ((float)yofs)/256.0;
|
||||||
|
icon->uv[1][0]= icon->uv[0][0] + ((float)w)/512.0;
|
||||||
|
icon->uv[1][1]= icon->uv[0][1];
|
||||||
|
icon->uv[2][0]= icon->uv[0][0] + ((float)w)/512.0;
|
||||||
|
icon->uv[2][1]= icon->uv[0][1] + ((float)w)/256.0;
|
||||||
|
icon->uv[3][0]= icon->uv[0][0];
|
||||||
|
icon->uv[3][1]= icon->uv[0][1] + ((float)w)/256.0;
|
||||||
|
|
||||||
icon->w= w;
|
icon->w= w;
|
||||||
icon->h= h;
|
icon->h= h;
|
||||||
|
|
||||||
|
icon->data= MEM_mallocN(w*h*4, "icon->data");
|
||||||
for (y=0; y<h; y++)
|
for (y=0; y<h; y++)
|
||||||
memcpy(&icon->data[y*w*4], &rect[y*rowstride], w*4);
|
memcpy(&icon->data[y*w*4], &rect[y*rowstride], w*4);
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static float icon_x=0.0, icon_y=0.0;
|
||||||
|
void BIF_icon_pos(float xs, float ys)
|
||||||
|
{
|
||||||
|
icon_x= xs; icon_y= ys;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLuint init_icon_texture(ImBuf *bbuf)
|
||||||
|
{
|
||||||
|
GLuint texid;
|
||||||
|
|
||||||
|
glGenTextures(1, &texid);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, texid);
|
||||||
|
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bbuf->x, bbuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, bbuf->rect);
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||||
|
|
||||||
|
return texid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* texture version for drawpixels */
|
||||||
|
static void icon_draw_tex(Icon *icon)
|
||||||
|
{
|
||||||
|
glBindTexture(GL_TEXTURE_2D, icon->texid);
|
||||||
|
|
||||||
|
/* drawing it */
|
||||||
|
glColor3ub(255, 255, 255);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
|
glTexCoord2fv(icon->uv[0]);
|
||||||
|
glVertex2f(icon_x, icon_y);
|
||||||
|
glTexCoord2fv(icon->uv[1]);
|
||||||
|
glVertex2f(icon_x+icon->w, icon_y);
|
||||||
|
glTexCoord2fv(icon->uv[2]);
|
||||||
|
glVertex2f(icon_x+icon->w, icon_y+icon->h);
|
||||||
|
glTexCoord2fv(icon->uv[3]);
|
||||||
|
glVertex2f(icon_x, icon_y+icon->h);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void icon_draw(Icon *icon)
|
static void icon_draw(Icon *icon)
|
||||||
{
|
{
|
||||||
glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
|
glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
static unsigned char colclamp(int val)
|
|
||||||
{
|
|
||||||
return (val<0)?(0):((val>255)?255:val);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void icon_draw_blended(Icon *icon, unsigned char blendcol[3])
|
|
||||||
{
|
|
||||||
unsigned char temprect[20*21*4]; /* XXX, not so safe */
|
|
||||||
unsigned char *bgcol= icon->data;
|
|
||||||
int blendfac[3];
|
|
||||||
int x, y;
|
|
||||||
|
|
||||||
blendfac[0]= bgcol[0]? (blendcol[0]<<8)/bgcol[0] : 0;
|
|
||||||
blendfac[1]= bgcol[1]? (blendcol[1]<<8)/bgcol[1] : 0;
|
|
||||||
blendfac[2]= bgcol[2]? (blendcol[2]<<8)/bgcol[2] : 0;
|
|
||||||
|
|
||||||
for (y=0; y<icon->h; y++) {
|
|
||||||
unsigned char *row= &icon->data[y*(icon->w*4)];
|
|
||||||
unsigned char *orow= &temprect[y*(icon->w*4)];
|
|
||||||
|
|
||||||
for (x=0; x<icon->w; x++) {
|
|
||||||
unsigned char *pxl= &row[x*4];
|
|
||||||
unsigned char *opxl= &orow[x*4];
|
|
||||||
|
|
||||||
opxl[0]= colclamp((pxl[0]*blendfac[0])>>8);
|
|
||||||
opxl[1]= colclamp((pxl[1]*blendfac[1])>>8);
|
|
||||||
opxl[2]= colclamp((pxl[2]*blendfac[2])>>8);
|
|
||||||
opxl[3]= pxl[3];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, temprect);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void icon_draw_blended(Icon *icon, char *blendcol, int shade)
|
static void icon_draw_blended(Icon *icon, char *blendcol, int shade)
|
||||||
{
|
{
|
||||||
/* commented out, for now only alpha (ton) */
|
|
||||||
// float r, g, b;
|
|
||||||
|
|
||||||
// r= (-shade + (float)blendcol[0])/180.0;
|
|
||||||
// g= (-shade + (float)blendcol[1])/180.0;
|
|
||||||
// b= (-shade + (float)blendcol[2])/180.0;
|
|
||||||
|
|
||||||
// glPixelTransferf(GL_RED_SCALE, r>0.0?r:0.0);
|
|
||||||
// glPixelTransferf(GL_GREEN_SCALE, g>0.0?g:0.0);
|
|
||||||
// glPixelTransferf(GL_BLUE_SCALE, b>0.0?b:0.0);
|
|
||||||
|
|
||||||
if(shade < 0) {
|
if(shade < 0) {
|
||||||
float r= (128+shade)/128.0;
|
float r= (128+shade)/128.0;
|
||||||
glPixelTransferf(GL_ALPHA_SCALE, r);
|
glPixelTransferf(GL_ALPHA_SCALE, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
|
glDrawPixels(icon->w, icon->h, GL_RGBA, GL_UNSIGNED_BYTE, icon->data);
|
||||||
|
|
||||||
// glPixelTransferf(GL_RED_SCALE, 1.0);
|
|
||||||
// glPixelTransferf(GL_GREEN_SCALE, 1.0);
|
|
||||||
// glPixelTransferf(GL_BLUE_SCALE, 1.0);
|
|
||||||
glPixelTransferf(GL_ALPHA_SCALE, 1.0);
|
glPixelTransferf(GL_ALPHA_SCALE, 1.0);
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -188,6 +197,8 @@ void BIF_draw_icon_blended(BIFIconID icon, int colorid, int shade)
|
|||||||
{
|
{
|
||||||
char *cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
|
char *cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
|
||||||
icon_draw_blended(get_icon(icon), cp, shade);
|
icon_draw_blended(get_icon(icon), cp, shade);
|
||||||
|
// icon_draw_tex(get_icon(icon));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int BIF_get_icon_width(BIFIconID icon)
|
int BIF_get_icon_width(BIFIconID icon)
|
||||||
@@ -200,13 +211,17 @@ int BIF_get_icon_height(BIFIconID icon)
|
|||||||
return get_icon(icon)->h;
|
return get_icon(icon)->h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void def_icon(ImBuf *bbuf, BIFIconID icon, int xidx, int yidx, int w, int h, int offsx, int offsy)
|
static void def_icon(ImBuf *bbuf, GLuint texid, BIFIconID icon, int xidx, int yidx, int w, int h, int offsx, int offsy)
|
||||||
{
|
{
|
||||||
int iconidx= icon-BIFICONID_FIRST;
|
int iconidx= icon-BIFICONID_FIRST;
|
||||||
|
|
||||||
if (iconidx>=0 && iconidx<BIFNICONIDS) {
|
if (iconidx>=0 && iconidx<BIFNICONIDS) {
|
||||||
int rowstride= bbuf->x*4;
|
int rowstride= bbuf->x*4;
|
||||||
unsigned char *start= ((char*) bbuf->rect) + (yidx*21 + 3 + offsy)*rowstride + (xidx*20 + 3 + offsx)*4;
|
unsigned char *start= ((char*) bbuf->rect) + (yidx*21 + 3 + offsy)*rowstride + (xidx*20 + 3 + offsx)*4;
|
||||||
common_icons_arr[iconidx]= icon_from_data(start, w, h, rowstride);
|
|
||||||
|
common_icons_arr[iconidx]=
|
||||||
|
icon_from_data(start, texid, (xidx*20 + 3 + offsx), (yidx*21 + 3 + offsy), w, h, rowstride);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
printf("def_icon: Internal error, bad icon ID: %d\n", icon);
|
printf("def_icon: Internal error, bad icon ID: %d\n", icon);
|
||||||
}
|
}
|
||||||
@@ -231,6 +246,7 @@ static void clear_transp_rect(unsigned char *transp, unsigned char *rect, int w,
|
|||||||
void BIF_resources_init(void)
|
void BIF_resources_init(void)
|
||||||
{
|
{
|
||||||
ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect);
|
ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect);
|
||||||
|
GLuint texid=0;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
|
||||||
common_icons_arr= MEM_mallocN(sizeof(*common_icons_arr)*BIFNICONIDS, "common_icons");
|
common_icons_arr= MEM_mallocN(sizeof(*common_icons_arr)*BIFNICONIDS, "common_icons");
|
||||||
@@ -240,23 +256,32 @@ void BIF_resources_init(void)
|
|||||||
int rowstride= bbuf->x*4;
|
int rowstride= bbuf->x*4;
|
||||||
unsigned char *start= ((char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4;
|
unsigned char *start= ((char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4;
|
||||||
unsigned char transp[4];
|
unsigned char transp[4];
|
||||||
|
/* this sets backdrop of icon to zero alpha */
|
||||||
transp[0]= start[0];
|
transp[0]= start[0];
|
||||||
transp[1]= start[1];
|
transp[1]= start[1];
|
||||||
transp[2]= start[2];
|
transp[2]= start[2];
|
||||||
transp[3]= start[3];
|
transp[3]= start[3];
|
||||||
clear_transp_rect(transp, start, 20, 21, rowstride);
|
clear_transp_rect(transp, start, 20, 21, rowstride);
|
||||||
|
|
||||||
|
/* this sets outside of icon to zero alpha */
|
||||||
|
start= ((char*) bbuf->rect) + (y*21)*rowstride + (x*20)*4;
|
||||||
|
QUATCOPY(transp, start);
|
||||||
|
clear_transp_rect(transp, start, 20, 21, rowstride);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disabled for now (ton)
|
||||||
|
// texid= init_icon_texture(bbuf);
|
||||||
|
|
||||||
/* hack! */
|
/* hack! */
|
||||||
for (y=0; y<10; y++) {
|
for (y=0; y<10; y++) {
|
||||||
for (x=0; x<21; x++) {
|
for (x=0; x<21; x++) {
|
||||||
if (x==11 && y==6) {
|
if (x==11 && y==6) {
|
||||||
def_icon(bbuf, ICON_BEVELBUT_HLT, x, y, 7, 13, 4, 2);
|
def_icon(bbuf, texid, ICON_BEVELBUT_HLT, x, y, 7, 13, 4, 2);
|
||||||
} else if (x==12 && y==6) {
|
} else if (x==12 && y==6) {
|
||||||
def_icon(bbuf, ICON_BEVELBUT_DEHLT, x, y, 7, 13, 4, 2);
|
def_icon(bbuf, texid, ICON_BEVELBUT_DEHLT, x, y, 7, 13, 4, 2);
|
||||||
} else {
|
} else {
|
||||||
def_icon(bbuf, BIFICONID_FIRST + y*21 + x, x, y, 15, 16, 0, 0);
|
def_icon(bbuf, texid, BIFICONID_FIRST + y*21 + x, x, y, 15, 16, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -633,7 +633,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
if(val) {
|
if(val) {
|
||||||
|
|
||||||
if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
|
if( uiDoBlocks(&curarea->uiblocks, event)!=UI_NOTHING ) event= 0;
|
||||||
if(event==MOUSEY) return;
|
if(event==MOUSEY || event==MOUSEX) return;
|
||||||
|
|
||||||
if(event==UI_BUT_EVENT) do_butspace(val); // temporal, view3d deserves own queue?
|
if(event==UI_BUT_EVENT) do_butspace(val); // temporal, view3d deserves own queue?
|
||||||
|
|
||||||
@@ -1117,7 +1117,6 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
case GKEY:
|
case GKEY:
|
||||||
/* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group();
|
/* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group();
|
||||||
else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */
|
else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */
|
||||||
|
|
||||||
if((G.qual==LR_SHIFTKEY))
|
if((G.qual==LR_SHIFTKEY))
|
||||||
select_group_menu();
|
select_group_menu();
|
||||||
else if(G.qual==LR_ALTKEY)
|
else if(G.qual==LR_ALTKEY)
|
||||||
@@ -1144,6 +1143,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
hideNurb(0);
|
hideNurb(0);
|
||||||
}
|
}
|
||||||
else if(G.obedit->type==OB_CURVE) {
|
else if(G.obedit->type==OB_CURVE) {
|
||||||
|
undo_push_curve("Handle change");
|
||||||
if(G.qual==LR_CTRLKEY)
|
if(G.qual==LR_CTRLKEY)
|
||||||
autocalchandlesNurb_all(1); /* flag=1, selected */
|
autocalchandlesNurb_all(1); /* flag=1, selected */
|
||||||
else if((G.qual==LR_SHIFTKEY))
|
else if((G.qual==LR_SHIFTKEY))
|
||||||
@@ -1418,8 +1418,16 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
}
|
}
|
||||||
else if(G.obedit->type==OB_ARMATURE)
|
else if(G.obedit->type==OB_ARMATURE)
|
||||||
remake_editArmature();
|
remake_editArmature();
|
||||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
|
||||||
remake_editNurb();
|
extern void undo_curve_step(int step);
|
||||||
|
if (G.qual==LR_ALTKEY)
|
||||||
|
//undo_menu_curve();
|
||||||
|
;
|
||||||
|
else if (G.qual==LR_SHIFTKEY)
|
||||||
|
undo_curve_step(-1);
|
||||||
|
else if((G.qual==0))
|
||||||
|
undo_curve_step(1);
|
||||||
|
}
|
||||||
else if(G.obedit->type==OB_LATTICE)
|
else if(G.obedit->type==OB_LATTICE)
|
||||||
remake_editLatt();
|
remake_editLatt();
|
||||||
}
|
}
|
||||||
@@ -1432,8 +1440,11 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
vpaint_undo();
|
vpaint_undo();
|
||||||
else
|
else
|
||||||
single_user();
|
single_user();
|
||||||
|
//BIF_undo_step(1);
|
||||||
}
|
}
|
||||||
|
else if(G.qual==LR_SHIFTKEY)
|
||||||
|
// BIF_undo_step(-1);
|
||||||
|
;
|
||||||
break;
|
break;
|
||||||
case VKEY:
|
case VKEY:
|
||||||
ob= OBACT;
|
ob= OBACT;
|
||||||
@@ -1450,6 +1461,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
else if (G.qual==0){
|
else if (G.qual==0){
|
||||||
if(G.obedit) {
|
if(G.obedit) {
|
||||||
if(G.obedit->type==OB_CURVE) {
|
if(G.obedit->type==OB_CURVE) {
|
||||||
|
undo_push_curve("Handle change");
|
||||||
sethandlesNurb(2);
|
sethandlesNurb(2);
|
||||||
makeDispList(G.obedit);
|
makeDispList(G.obedit);
|
||||||
allqueue(REDRAWVIEW3D, 0);
|
allqueue(REDRAWVIEW3D, 0);
|
||||||
|
|||||||
@@ -107,6 +107,7 @@
|
|||||||
|
|
||||||
#include "BDR_drawobject.h"
|
#include "BDR_drawobject.h"
|
||||||
#include "BDR_editobject.h"
|
#include "BDR_editobject.h"
|
||||||
|
#include "BDR_editcurve.h"
|
||||||
#include "BDR_vpaint.h"
|
#include "BDR_vpaint.h"
|
||||||
|
|
||||||
#include "BPY_extern.h"
|
#include "BPY_extern.h"
|
||||||
@@ -126,7 +127,10 @@
|
|||||||
void BIF_read_file(char *name)
|
void BIF_read_file(char *name)
|
||||||
{
|
{
|
||||||
extern short winqueue_break; /* editscreen.c */
|
extern short winqueue_break; /* editscreen.c */
|
||||||
|
void BIF_reset_undo(void);
|
||||||
|
void BIF_write_undo(char *);
|
||||||
|
|
||||||
|
BIF_reset_undo();
|
||||||
|
|
||||||
//here?
|
//here?
|
||||||
//sound_end_all_sounds();
|
//sound_end_all_sounds();
|
||||||
@@ -145,6 +149,7 @@ void BIF_read_file(char *name)
|
|||||||
|
|
||||||
winqueue_break= 1; /* leave queues everywhere */
|
winqueue_break= 1; /* leave queues everywhere */
|
||||||
|
|
||||||
|
BIF_write_undo("original"); /* save current state */
|
||||||
}
|
}
|
||||||
|
|
||||||
int BIF_read_homefile(void)
|
int BIF_read_homefile(void)
|
||||||
@@ -459,6 +464,123 @@ static void delete_autosave(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***/
|
||||||
|
|
||||||
|
#define MAXUNDONAME 64
|
||||||
|
typedef struct UndoElem {
|
||||||
|
struct UndoElem *next, *prev;
|
||||||
|
char str[FILE_MAXDIR+FILE_MAXFILE];
|
||||||
|
char name[MAXUNDONAME];
|
||||||
|
} UndoElem;
|
||||||
|
|
||||||
|
#define MAXUNDO 32
|
||||||
|
static ListBase undobase={NULL, NULL};
|
||||||
|
static UndoElem *curundo= NULL;
|
||||||
|
|
||||||
|
static void get_undosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE], int num)
|
||||||
|
{
|
||||||
|
char numstr[32];
|
||||||
|
|
||||||
|
sprintf(numstr, "%d.blend", num);
|
||||||
|
BLI_make_file_string("/", buf, U.tempdir, numstr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_undosave(char *tstr)
|
||||||
|
{
|
||||||
|
char scestr[FILE_MAXDIR+FILE_MAXFILE];
|
||||||
|
int success;
|
||||||
|
|
||||||
|
strcpy(scestr, G.sce); /* temporal store */
|
||||||
|
|
||||||
|
success= BKE_read_file(tstr, NULL);
|
||||||
|
strcpy(G.sce, scestr);
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* name can be a dynamic string */
|
||||||
|
void BIF_write_undo(char *name)
|
||||||
|
{
|
||||||
|
static int counter= 0;
|
||||||
|
int nr;
|
||||||
|
char *err, tstr[FILE_MAXDIR+FILE_MAXFILE];
|
||||||
|
UndoElem *uel;
|
||||||
|
|
||||||
|
/* calculate current filename */
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
counter= counter % MAXUNDO;
|
||||||
|
get_undosave_location(tstr, counter);
|
||||||
|
|
||||||
|
if(BLO_write_file(tstr, G.fileflags, &err)) {
|
||||||
|
|
||||||
|
/* remove all undos after (also when curundo==NULL) */
|
||||||
|
while(undobase.last != curundo) {
|
||||||
|
uel= undobase.last;
|
||||||
|
BLI_remlink(&undobase, uel);
|
||||||
|
MEM_freeN(uel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make new */
|
||||||
|
curundo= uel= MEM_mallocN(sizeof(UndoElem), "undo file");
|
||||||
|
strcpy(uel->str, tstr);
|
||||||
|
strncpy(uel->name, name, MAXUNDONAME-1);
|
||||||
|
BLI_addtail(&undobase, uel);
|
||||||
|
|
||||||
|
/* and limit amount to the maximum */
|
||||||
|
nr= 0;
|
||||||
|
uel= undobase.last;
|
||||||
|
while(uel) {
|
||||||
|
nr++;
|
||||||
|
if(nr==MAXUNDO) break;
|
||||||
|
uel= uel->prev;
|
||||||
|
}
|
||||||
|
if(uel) {
|
||||||
|
while(undobase.first!=uel) {
|
||||||
|
UndoElem *first= undobase.first;
|
||||||
|
BLI_remlink(&undobase, first);
|
||||||
|
MEM_freeN(first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */
|
||||||
|
void BIF_undo_step(int step)
|
||||||
|
{
|
||||||
|
|
||||||
|
if(step==1) {
|
||||||
|
/* curundo should never be NULL, after restart or load file it should call undo_save */
|
||||||
|
if(curundo==NULL || curundo->prev==NULL) error("No undo available");
|
||||||
|
else {
|
||||||
|
printf("undo %s\n", curundo->name);
|
||||||
|
curundo= curundo->prev;
|
||||||
|
read_undosave(curundo->str);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
/* curundo has to remain current situation! */
|
||||||
|
|
||||||
|
if(curundo==NULL || curundo->next==NULL) error("No redo available");
|
||||||
|
else {
|
||||||
|
read_undosave(curundo->next->str);
|
||||||
|
curundo= curundo->next;
|
||||||
|
printf("redo %s\n", curundo->name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void BIF_reset_undo(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
BLI_freelistN(&undobase);
|
||||||
|
curundo= NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***/
|
/***/
|
||||||
|
|
||||||
static void initbuttons(void)
|
static void initbuttons(void)
|
||||||
@@ -576,7 +698,9 @@ void exit_usiblender(void)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (G.undo_clear) G.undo_clear();
|
if (G.undo_clear) G.undo_clear();
|
||||||
|
undo_clear_curve();
|
||||||
|
BIF_reset_undo();
|
||||||
|
|
||||||
BLI_freelistN(&U.themes);
|
BLI_freelistN(&U.themes);
|
||||||
|
|
||||||
if(totblock!=0) {
|
if(totblock!=0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user