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);
|
||||
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 */
|
||||
|
||||
|
||||
@@ -209,7 +209,8 @@ extern void ui_window_to_graphics(int win, float *x, float *y);
|
||||
/* interface_panel.c */
|
||||
extern void ui_draw_panel(uiBlock *block);
|
||||
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 */
|
||||
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;
|
||||
|
||||
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");
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
#include "DNA_scene_types.h"
|
||||
#include "DNA_screen_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_library.h"
|
||||
@@ -1043,6 +1044,8 @@ void switchdirectionNurb2(void)
|
||||
if(G.obedit->lay & G.vd->lay);
|
||||
else return;
|
||||
|
||||
undo_push_curve("Switch direction");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if( isNurbsel(nu) ) switchdirectionNurb(nu);
|
||||
@@ -1106,6 +1109,8 @@ void deselectall_nurb()
|
||||
if(G.obedit->lay & G.vd->lay);
|
||||
else return;
|
||||
|
||||
undo_push_curve("Deselect all");
|
||||
|
||||
a= 0;
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
@@ -1194,6 +1199,8 @@ void hideNurb(int swap)
|
||||
|
||||
if(G.obedit==0) return;
|
||||
|
||||
undo_push_curve("Hide");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if((nu->type & 7)==CU_BEZIER) {
|
||||
@@ -1249,6 +1256,8 @@ void revealNurb()
|
||||
|
||||
if(G.obedit==0) return;
|
||||
|
||||
undo_push_curve("Reveal");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
nu->hide= 0;
|
||||
@@ -1293,6 +1302,8 @@ void selectswapNurb()
|
||||
|
||||
if(G.obedit==0) return;
|
||||
|
||||
undo_push_curve("Select swap");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if((nu->type & 7)==CU_BEZIER) {
|
||||
@@ -1346,6 +1357,8 @@ void subdivideNurb()
|
||||
|
||||
// printf("*** subdivideNurb: entering subdivide\n");
|
||||
|
||||
undo_push_curve("Subdivide");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
amount= 0;
|
||||
@@ -1868,6 +1881,8 @@ void setsplinetype(short type)
|
||||
return;
|
||||
}
|
||||
|
||||
undo_push_curve("Set spline type");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if(isNurbsel(nu)) {
|
||||
@@ -2248,6 +2263,8 @@ void merge_nurb()
|
||||
return;
|
||||
}
|
||||
|
||||
undo_push_curve("Merge");
|
||||
|
||||
nus1= nsortbase.first;
|
||||
nus2= nus1->next;
|
||||
|
||||
@@ -2296,6 +2313,8 @@ void addsegment_nurb()
|
||||
float *fp, offset;
|
||||
int a;
|
||||
|
||||
undo_push_curve("Add segment");
|
||||
|
||||
/* first decide if this is a surface merge! */
|
||||
if(G.obedit->type==OB_SURF) nu= editNurb.first;
|
||||
else nu= NULL;
|
||||
@@ -2450,6 +2469,8 @@ void mouse_nurb()
|
||||
BPoint *bp=0;
|
||||
short hand;
|
||||
|
||||
undo_push_curve("Select");
|
||||
|
||||
hand= findnearestNurbvert(1, &nu, &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.vd->lay & G.obedit->lay)==0 ) return;
|
||||
|
||||
undo_push_curve("Spin");
|
||||
|
||||
Mat3CpyMat4(persmat, G.vd->viewmat);
|
||||
Mat3Inv(persinv, persmat);
|
||||
|
||||
@@ -2642,6 +2665,8 @@ void addvert_Nurb(int mode)
|
||||
|
||||
if(mode=='e' && okee("Extrude")==0) return;
|
||||
|
||||
undo_push_curve("Add vertex");
|
||||
|
||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||
Mat3Inv(imat,mat);
|
||||
|
||||
@@ -2759,6 +2784,21 @@ void addvert_Nurb(int mode)
|
||||
|
||||
if(mode=='e') transform('d');
|
||||
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()
|
||||
@@ -2780,6 +2820,8 @@ void extrude_nurb()
|
||||
else {
|
||||
|
||||
if(okee("Extrude")==0) return;
|
||||
undo_push_curve("Extrude");
|
||||
|
||||
ok= extrudeflagNurb(1); /* '1'= flag */
|
||||
|
||||
if(ok) {
|
||||
@@ -2801,6 +2843,8 @@ void makecyclicNurb()
|
||||
float *fp;
|
||||
int a, b, cyclmode=0;
|
||||
|
||||
undo_push_curve("Cyclic");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if( nu->pntsu>1 || nu->pntsv>1) {
|
||||
@@ -2906,6 +2950,8 @@ void selectconnected_nurb()
|
||||
BPoint *bp;
|
||||
int a;
|
||||
|
||||
undo_push_curve("Select connected");
|
||||
|
||||
findnearestNurbvert(1, &nu, &bezt, &bp);
|
||||
if(bezt) {
|
||||
a= nu->pntsu;
|
||||
@@ -2958,6 +3004,8 @@ void selectrow_nurb()
|
||||
if(G.obedit==NULL || G.obedit->type!=OB_SURF) return;
|
||||
if(lastselbp==NULL) return;
|
||||
|
||||
undo_push_curve("Select Row");
|
||||
|
||||
/* find the correct nurb and toggle with u of v */
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
@@ -3004,6 +3052,8 @@ void adduplicate_nurb()
|
||||
|
||||
if( (G.vd->lay & G.obedit->lay)==0 ) return;
|
||||
|
||||
undo_push_curve("Duplicate");
|
||||
|
||||
adduplicateflagNurb(1);
|
||||
|
||||
countall();
|
||||
@@ -3026,6 +3076,8 @@ void delNurb()
|
||||
|
||||
if(event== -1) return;
|
||||
|
||||
undo_push_curve("Delete");
|
||||
|
||||
if(G.obedit->type==OB_SURF) {
|
||||
if(event==0) deleteflagNurb(1);
|
||||
else freeNurblist(&editNurb);
|
||||
@@ -3302,6 +3354,8 @@ void join_curve(int type)
|
||||
}
|
||||
else if(okee("Join selected curves")==0) return;
|
||||
|
||||
undo_push_curve("Join");
|
||||
|
||||
/* trasnform all selected curves inverse in obact */
|
||||
Mat4Invert(imat, ob->obmat);
|
||||
|
||||
@@ -3813,7 +3867,10 @@ void add_primitiveCurve(int stype)
|
||||
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;
|
||||
|
||||
@@ -3850,6 +3907,9 @@ void add_primitiveNurb(int type)
|
||||
setcursor_space(SPACE_VIEW3D, CURSOR_EDIT);
|
||||
newname= 1;
|
||||
}
|
||||
else {
|
||||
undo_push_curve("Add primitive");
|
||||
}
|
||||
|
||||
nu= addNurbprim(4, type, newname);
|
||||
BLI_addtail(&editNurb,nu);
|
||||
@@ -3870,6 +3930,8 @@ void clear_tilt()
|
||||
|
||||
if(okee("Clear tilt")==0) return;
|
||||
|
||||
undo_push_curve("Clear tilt");
|
||||
|
||||
nu= editNurb.first;
|
||||
while(nu) {
|
||||
if( nu->bezt ) {
|
||||
@@ -3895,70 +3957,6 @@ void clear_tilt()
|
||||
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)
|
||||
{
|
||||
BezTriple *b1 = *((BezTriple**)e1);
|
||||
@@ -3982,3 +3980,165 @@ int bezt_compare (const void *e1, const void *e2)
|
||||
|
||||
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 (G.obedit && G.obedit->type == OB_MESH) {
|
||||
if (G.obedit) {
|
||||
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? */
|
||||
@@ -7424,6 +7427,8 @@ void mirror_edit(short mode) {
|
||||
TransVert *tv;
|
||||
|
||||
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);
|
||||
Mat3CpyMat4(mat, G.obedit->obmat);
|
||||
|
||||
@@ -1796,6 +1796,7 @@ static int ui_do_but_NUMSLI(uiBut *but)
|
||||
}
|
||||
else {
|
||||
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();
|
||||
@@ -3090,6 +3091,8 @@ static int ui_do_block(uiBlock *block, uiEvent *uevent)
|
||||
if(inside || uevent->event!=LEFTMOUSE) {
|
||||
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);
|
||||
|
||||
/* i doubt about the next line! */
|
||||
@@ -3198,15 +3201,13 @@ static uiSaveUnder *ui_draw_but_tip(uiBut *but)
|
||||
|
||||
glColor4ub(0, 0, 0, 20);
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(x1+3, y1-1, x2+1, y2-2, 2.0);
|
||||
gl_round_box(x1+3, y1-2, x2+2, y2-2, 3.0);
|
||||
gl_round_box(GL_POLYGON, 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);
|
||||
|
||||
glColor4ub(0, 0, 0, 8);
|
||||
|
||||
gl_round_box(x1+3, y1-3, x2+3, y2-3, 4.0);
|
||||
gl_round_box(x1+3, y1-4, x2+4, y2-3, 5.0);
|
||||
glEnd();
|
||||
gl_round_box(GL_POLYGON, x1+3, y1-3, x2+3, y2-3, 4.0);
|
||||
gl_round_box(GL_POLYGON, x1+3, y1-4, x2+4, y2-3, 5.0);
|
||||
|
||||
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)
|
||||
{
|
||||
void BIF_icon_pos(float xs, float ys);
|
||||
int blend= 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->type==BUTM) {
|
||||
xs= but->x1+1.0;
|
||||
@@ -145,6 +149,7 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
||||
}
|
||||
|
||||
glRasterPos2f(xs, ys);
|
||||
// BIF_icon_pos(xs, ys);
|
||||
|
||||
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);
|
||||
@@ -160,24 +165,6 @@ static void ui_draw_icon(uiBut *but, BIFIconID icon)
|
||||
}
|
||||
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);
|
||||
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);
|
||||
} else {
|
||||
MM_DARK;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(x1, y1, x2, y2, 1.5);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
|
||||
}
|
||||
/* 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);
|
||||
} else {
|
||||
MM_DARK;
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(x1, y1, x2, y2, 1.5);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, 1.5);
|
||||
}
|
||||
/* 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;
|
||||
if(rad>7.0) rad= 7.0;
|
||||
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(x1, y1, x2, y2, rad);
|
||||
glEnd();
|
||||
/* the shaded round_box version (0.1 is shade factor) */
|
||||
//gl_round_box_shade(GL_POLYGON, x1, y1, x2, y2, rad, 0.1);
|
||||
|
||||
gl_round_box(GL_POLYGON, x1, y1, x2, y2, rad);
|
||||
|
||||
BIF_ThemeColorBlendShade(colorid, TH_BACK, 0.5, -70);
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(x1, y1, x2, y2, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, x1, y1, x2, y2, rad);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
else BIF_ThemeColorShade(colorid, -10);
|
||||
// assuming its not inside alignment...
|
||||
uiSetRoundBox(6);
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(x2-9, y1+asp, x2-asp, y2-asp, 7.0);
|
||||
glEnd();
|
||||
uiSetRoundBox(round_align_fix);
|
||||
gl_round_box(GL_POLYGON, x2-9, y1+asp, x2-asp, y2-asp, 7.0);
|
||||
|
||||
BIF_ThemeColorShade(colorid, -60);
|
||||
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...
|
||||
if(x2-x1 > 24) {
|
||||
uiSetRoundBox(round_align_fix);
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(x2-16, y1+asp, x2-asp, y2-asp, 7.0);
|
||||
glEnd();
|
||||
gl_round_box(GL_POLYGON, x2-16, y1+asp, x2-asp, y2-asp, 7.0);
|
||||
}
|
||||
BIF_ThemeColorShade(colorid, -60);
|
||||
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},
|
||||
{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();
|
||||
}
|
||||
|
||||
|
||||
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 */
|
||||
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 */
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
|
||||
|
||||
/* set antialias line */
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
@@ -243,9 +361,7 @@ void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad)
|
||||
|
||||
/* total outline */
|
||||
if(roundboxtype & UI_RB_ALPHA) glColor4ub(0,0,0, 128); else glColor4ub(0,0,0, 255);
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
@@ -276,9 +392,7 @@ void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
@@ -300,18 +414,14 @@ void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad)
|
||||
}
|
||||
|
||||
/* solid part */
|
||||
glBegin(GL_POLYGON);
|
||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_POLYGON, minx, miny, maxx, maxy, rad);
|
||||
|
||||
/* set antialias line */
|
||||
glEnable( GL_LINE_SMOOTH );
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
|
||||
glBegin(GL_LINE_LOOP);
|
||||
gl_round_box(minx, miny, maxx, maxy, rad);
|
||||
glEnd();
|
||||
gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
|
||||
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_LINE_SMOOTH );
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
|
||||
|
||||
/**
|
||||
* $Id$
|
||||
*
|
||||
@@ -67,86 +65,97 @@ static int theme_spacetype= SPACE_VIEW3D;
|
||||
|
||||
typedef struct {
|
||||
unsigned char *data;
|
||||
float uv[4][2];
|
||||
GLuint texid;
|
||||
int w, h;
|
||||
} 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");
|
||||
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->h= h;
|
||||
|
||||
icon->data= MEM_mallocN(w*h*4, "icon->data");
|
||||
for (y=0; y<h; y++)
|
||||
memcpy(&icon->data[y*w*4], &rect[y*rowstride], w*4);
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
/* 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) {
|
||||
float r= (128+shade)/128.0;
|
||||
glPixelTransferf(GL_ALPHA_SCALE, r);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
}
|
||||
@@ -188,6 +197,8 @@ void BIF_draw_icon_blended(BIFIconID icon, int colorid, int shade)
|
||||
{
|
||||
char *cp= BIF_ThemeGetColorPtr(theme_active, theme_spacetype, colorid);
|
||||
icon_draw_blended(get_icon(icon), cp, shade);
|
||||
// icon_draw_tex(get_icon(icon));
|
||||
|
||||
}
|
||||
|
||||
int BIF_get_icon_width(BIFIconID icon)
|
||||
@@ -200,13 +211,17 @@ int BIF_get_icon_height(BIFIconID icon)
|
||||
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;
|
||||
|
||||
if (iconidx>=0 && iconidx<BIFNICONIDS) {
|
||||
int rowstride= bbuf->x*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 {
|
||||
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)
|
||||
{
|
||||
ImBuf *bbuf= IMB_ibImageFromMemory((int *)datatoc_blenderbuttons, datatoc_blenderbuttons_size, IB_rect);
|
||||
GLuint texid=0;
|
||||
int x, y;
|
||||
|
||||
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;
|
||||
unsigned char *start= ((char*) bbuf->rect) + (y*21 + 3)*rowstride + (x*20 + 3)*4;
|
||||
unsigned char transp[4];
|
||||
/* this sets backdrop of icon to zero alpha */
|
||||
transp[0]= start[0];
|
||||
transp[1]= start[1];
|
||||
transp[2]= start[2];
|
||||
transp[3]= start[3];
|
||||
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! */
|
||||
for (y=0; y<10; y++) {
|
||||
for (x=0; x<21; x++) {
|
||||
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) {
|
||||
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 {
|
||||
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( 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?
|
||||
|
||||
@@ -1117,7 +1117,6 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case GKEY:
|
||||
/* RMGRP if(G.qual & LR_CTRLKEY) add_selected_to_group();
|
||||
else if(G.qual & LR_ALTKEY) rem_selected_from_group(); */
|
||||
|
||||
if((G.qual==LR_SHIFTKEY))
|
||||
select_group_menu();
|
||||
else if(G.qual==LR_ALTKEY)
|
||||
@@ -1144,6 +1143,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
hideNurb(0);
|
||||
}
|
||||
else if(G.obedit->type==OB_CURVE) {
|
||||
undo_push_curve("Handle change");
|
||||
if(G.qual==LR_CTRLKEY)
|
||||
autocalchandlesNurb_all(1); /* flag=1, selected */
|
||||
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)
|
||||
remake_editArmature();
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF)
|
||||
remake_editNurb();
|
||||
else if ELEM(G.obedit->type, OB_CURVE, OB_SURF) {
|
||||
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)
|
||||
remake_editLatt();
|
||||
}
|
||||
@@ -1432,8 +1440,11 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
vpaint_undo();
|
||||
else
|
||||
single_user();
|
||||
//BIF_undo_step(1);
|
||||
}
|
||||
|
||||
else if(G.qual==LR_SHIFTKEY)
|
||||
// BIF_undo_step(-1);
|
||||
;
|
||||
break;
|
||||
case VKEY:
|
||||
ob= OBACT;
|
||||
@@ -1450,6 +1461,7 @@ void winqreadview3dspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
else if (G.qual==0){
|
||||
if(G.obedit) {
|
||||
if(G.obedit->type==OB_CURVE) {
|
||||
undo_push_curve("Handle change");
|
||||
sethandlesNurb(2);
|
||||
makeDispList(G.obedit);
|
||||
allqueue(REDRAWVIEW3D, 0);
|
||||
|
||||
@@ -107,6 +107,7 @@
|
||||
|
||||
#include "BDR_drawobject.h"
|
||||
#include "BDR_editobject.h"
|
||||
#include "BDR_editcurve.h"
|
||||
#include "BDR_vpaint.h"
|
||||
|
||||
#include "BPY_extern.h"
|
||||
@@ -126,7 +127,10 @@
|
||||
void BIF_read_file(char *name)
|
||||
{
|
||||
extern short winqueue_break; /* editscreen.c */
|
||||
void BIF_reset_undo(void);
|
||||
void BIF_write_undo(char *);
|
||||
|
||||
BIF_reset_undo();
|
||||
|
||||
//here?
|
||||
//sound_end_all_sounds();
|
||||
@@ -145,6 +149,7 @@ void BIF_read_file(char *name)
|
||||
|
||||
winqueue_break= 1; /* leave queues everywhere */
|
||||
|
||||
BIF_write_undo("original"); /* save current state */
|
||||
}
|
||||
|
||||
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)
|
||||
@@ -576,6 +698,8 @@ void exit_usiblender(void)
|
||||
#endif
|
||||
|
||||
if (G.undo_clear) G.undo_clear();
|
||||
undo_clear_curve();
|
||||
BIF_reset_undo();
|
||||
|
||||
BLI_freelistN(&U.themes);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user