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:
2004-08-31 13:43:18 +00:00
parent 19a24abcb2
commit 0a305446a5
11 changed files with 668 additions and 248 deletions

View File

@@ -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 */

View File

@@ -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);

View File

@@ -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);

View File

@@ -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;
}
/***/

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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 );

View File

@@ -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);
} }
} }
} }

View File

@@ -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);

View File

@@ -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) {