Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/screen.c30
-rw-r--r--source/blender/blenloader/intern/readfile.c48
-rw-r--r--source/blender/blenloader/intern/writefile.c9
-rw-r--r--source/blender/editors/include/ED_anim_api.h1
-rw-r--r--source/blender/editors/include/UI_interface.h17
-rw-r--r--source/blender/editors/interface/interface.c65
-rw-r--r--source/blender/editors/interface/interface_draw.c64
-rw-r--r--source/blender/editors/interface/interface_handlers.c17
-rw-r--r--source/blender/editors/interface/interface_icons.c2
-rw-r--r--source/blender/editors/interface/interface_intern.h (renamed from source/blender/editors/interface/interface.h)22
-rw-r--r--source/blender/editors/interface/interface_panel.c1610
-rw-r--r--source/blender/editors/interface/interface_regions.c13
-rw-r--r--source/blender/editors/interface/view2d.c2
-rw-r--r--source/blender/editors/screen/area.c21
-rw-r--r--source/blender/editors/screen/screen_edit.c2
-rw-r--r--source/blender/editors/space_action/action_draw.c4
-rw-r--r--source/blender/editors/space_action/action_header.c2
-rw-r--r--source/blender/editors/space_buttons/Makefile1
-rw-r--r--source/blender/editors/space_buttons/SConscript1
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c5
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h3
-rw-r--r--source/blender/editors/space_buttons/buttons_scene.c324
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c15
-rw-r--r--source/blender/editors/space_file/file_header.c2
-rw-r--r--source/blender/editors/space_image/image_header.c2
-rw-r--r--source/blender/editors/space_info/info_header.c2
-rw-r--r--source/blender/editors/space_ipo/ipo_header.c2
-rw-r--r--source/blender/editors/space_nla/nla_header.c2
-rw-r--r--source/blender/editors/space_node/node_draw.c6
-rw-r--r--source/blender/editors/space_node/node_header.c2
-rw-r--r--source/blender/editors/space_outliner/outliner.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_header.c2
-rw-r--r--source/blender/editors/space_outliner/space_outliner.c2
-rw-r--r--source/blender/editors/space_script/script_header.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_header.c2
-rw-r--r--source/blender/editors/space_sound/sound_header.c2
-rw-r--r--source/blender/editors/space_text/text_header.c2
-rw-r--r--source/blender/editors/space_time/time_header.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c2
-rw-r--r--source/blender/makesdna/DNA_screen_types.h12
-rw-r--r--source/blender/makesdna/DNA_space_types.h10
41 files changed, 2169 insertions, 167 deletions
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index 74e30984436..b46d4af8887 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -123,6 +123,7 @@ void BKE_spacedata_freelist(ListBase *lb)
ARegion *BKE_area_region_copy(ARegion *ar)
{
ARegion *newar= MEM_dupallocN(ar);
+ Panel *pa, *newpa, *patab;
newar->handlers.first= newar->handlers.last= NULL;
newar->uiblocks.first= newar->uiblocks.last= NULL;
@@ -131,6 +132,23 @@ ARegion *BKE_area_region_copy(ARegion *ar)
/* XXX regiondata callback */
if(ar->regiondata)
newar->regiondata= MEM_dupallocN(ar->regiondata);
+
+ newar->panels.first= newar->panels.last= NULL;
+ BLI_duplicatelist(&newar->panels, &ar->panels);
+
+ /* copy panel pointers */
+ for(newpa= newar->panels.first; newpa; newpa= newpa->next) {
+ patab= newar->panels.first;
+ pa= ar->panels.first;
+ while(patab) {
+ if(newpa->paneltab == pa) {
+ newpa->paneltab = patab;
+ break;
+ }
+ patab= patab->next;
+ pa= pa->next;
+ }
+ }
return newar;
}
@@ -174,8 +192,12 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2)
/* not region itself */
void BKE_area_region_free(ARegion *ar)
{
- if(ar && ar->type && ar->type->free)
- ar->type->free(ar);
+ if(ar) {
+ if(ar->type && ar->type->free)
+ ar->type->free(ar);
+
+ BLI_freelistN(&ar->panels);
+ }
}
/* not area itself */
@@ -193,10 +215,6 @@ void BKE_screen_area_free(ScrArea *sa)
BLI_freelistN(&sa->regionbase);
BLI_freelistN(&sa->actionzones);
- BLI_freelistN(&sa->panels);
- // uiFreeBlocks(&sa->uiblocks);
- // uiFreePanels(&sa->panels);
-
#ifndef DISABLE_PYTHON
BPY_free_scriptlink(&sa->scriptlink);
#endif
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 2d8d9810b32..c7aa86b2bf5 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -3560,7 +3560,7 @@ static void direct_link_scene(FileData *fd, Scene *sce)
if(sce->sculptdata.cumap)
direct_link_curvemapping(fd, sce->sculptdata.cumap);
else
- ; //XXX sculpt_reset_curve(&sce->sculptdata);
+ sculpt_reset_curve(&sce->sculptdata);
if(sce->ed) {
ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase;
@@ -4150,6 +4150,17 @@ void lib_link_screen_restore(Main *newmain, Scene *curscene)
static void direct_link_region(FileData *fd, ARegion *ar)
{
+ Panel *pa;
+
+ link_list(fd, &(ar->panels));
+
+ for(pa= ar->panels.first; pa; pa=pa->next) {
+ pa->paneltab= newdataadr(fd, pa->paneltab);
+ pa->active= 0;
+ pa->sortcounter= 0;
+ pa->activedata= NULL;
+ }
+
ar->handlers.first= ar->handlers.last= NULL;
ar->uiblocks.first= ar->uiblocks.last= NULL;
ar->headerstr= NULL;
@@ -4200,16 +4211,13 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
/* areas */
for(sa= sc->areabase.first; sa; sa= sa->next) {
- Panel *pa;
SpaceLink *sl;
ARegion *ar;
link_list(fd, &(sa->spacedata));
- link_list(fd, &(sa->panels));
link_list(fd, &(sa->regionbase));
sa->handlers.first= sa->handlers.last= NULL;
- sa->uiblocks.first= sa->uiblocks.last= NULL;
sa->type= NULL; /* spacetype callbacks */
/* accident can happen when read/save new file with older version */
@@ -4220,12 +4228,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
BLI_addtail(&sa->spacedata, sinfo);
}
- for(pa= sa->panels.first; pa; pa=pa->next) {
- pa->paneltab= newdataadr(fd, pa->paneltab);
- pa->active= 0;
- pa->sortcounter= 0;
- }
-
for (sl= sa->spacedata.first; sl; sl= sl->next) {
link_list(fd, &(sl->regionbase));
@@ -4705,19 +4707,19 @@ static void vcol_to_fcol(Mesh *me)
static int map_223_keybd_code_to_224_keybd_code(int code)
{
switch (code) {
-//XXX case 312: return F12KEY;
-//XXX case 159: return PADSLASHKEY;
-//XXX case 161: return PAD0;
-//XXX case 154: return PAD1;
-//XXX case 150: return PAD2;
-//XXX case 155: return PAD3;
-//XXX case 151: return PAD4;
-//XXX case 156: return PAD5;
-//XXX case 152: return PAD6;
-//XXX case 157: return PAD7;
-//XXX case 153: return PAD8;
-//XXX case 158: return PAD9;
- default: return code;
+ case 312: return 311; /* F12KEY */
+ case 159: return 161; /* PADSLASHKEY */
+ case 161: return 150; /* PAD0 */
+ case 154: return 151; /* PAD1 */
+ case 150: return 152; /* PAD2 */
+ case 155: return 153; /* PAD3 */
+ case 151: return 154; /* PAD4 */
+ case 156: return 155; /* PAD5 */
+ case 152: return 156; /* PAD6 */
+ case 157: return 157; /* PAD7 */
+ case 153: return 158; /* PAD8 */
+ case 158: return 159; /* PAD9 */
+ default: return code;
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index ab5a6745686..33f33c79e31 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1655,12 +1655,13 @@ static void write_screens(WriteData *wd, ListBase *scrbase)
writestruct(wd, DATA, "ScrArea", 1, sa);
- for(pa= sa->panels.first; pa; pa= pa->next)
- writestruct(wd, DATA, "Panel", 1, pa);
-
- for(ar= sa->regionbase.first; ar; ar= ar->next)
+ for(ar= sa->regionbase.first; ar; ar= ar->next) {
writestruct(wd, DATA, "ARegion", 1, ar);
+ for(pa= ar->panels.first; pa; pa= pa->next)
+ writestruct(wd, DATA, "Panel", 1, pa);
+ }
+
/* space handler scriptlinks */
write_scriptlink(wd, &sa->scriptlink);
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index adc2f3a8c4c..b6908205398 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -39,6 +39,7 @@ struct View2D;
struct gla2DDrawInfo;
struct Object;
struct bActionGroup;
+struct Ipo;
struct IpoCurve;
/* ************************************************ */
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 6d0c12210de..3b0c9beb70b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -176,7 +176,6 @@ typedef struct uiBlock uiBlock;
/* Common Drawing Functions */
void uiEmboss(float x1, float y1, float x2, float y2, int sel);
-void uiRoundBoxEmboss(float minx, float miny, float maxx, float maxy, float rad, int active);
void uiRoundBox(float minx, float miny, float maxx, float maxy, float rad);
void uiSetRoundBox(int type);
void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad);
@@ -222,12 +221,13 @@ void uiPupmenuError(struct bContext *C, char *str, ...);
uiBlock *uiBeginBlock(const struct bContext *C, struct ARegion *region, char *name, short dt, short font);
void uiEndBlock(const struct bContext *C, uiBlock *block);
+void uiDrawBlock(const struct bContext *C, struct uiBlock *block);
uiBlock *uiGetBlock(char *name, struct ARegion *ar);
void uiFreeBlock(const struct bContext *C, uiBlock *block);
void uiFreeBlocks(const struct bContext *C, struct ListBase *lb);
+void uiFreeInactiveBlocks(const struct bContext *C, struct ListBase *lb);
void uiBoundsBlock(struct uiBlock *block, int addval);
-void uiDrawBlock(struct uiBlock *block);
void uiTextBoundsBlock(uiBlock *block, int addval);
void uiBlockSetButLock(uiBlock *block, int val, char *lockstr);
@@ -357,18 +357,16 @@ void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(struct bContext *C, u
extern void uiFreePanels(struct ListBase *lb);
extern void uiNewPanelTabbed(char *, char *);
-extern int uiNewPanel(struct ScrArea *sa, struct uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey);
+extern int uiNewPanel(const struct bContext *C, struct ARegion *ar, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey);
+extern void uiDrawPanels(const struct bContext *C, int re_align);
-extern void uiSetPanel_view2d(struct ScrArea *sa);
-extern void uiMatchPanel_view2d(struct ScrArea *sa);
+extern void uiSetPanelsView2d(struct ARegion *ar);
+extern void uiMatchPanelsView2d(struct ARegion *ar);
-extern void uiDrawBlocksPanels(struct ScrArea *sa, int re_align);
extern void uiNewPanelHeight(struct uiBlock *block, int sizey);
extern void uiNewPanelTitle(struct uiBlock *block, char *str);
-extern void uiPanelPush(struct uiBlock *block);
-extern void uiPanelPop(struct uiBlock *block);
extern uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name);
-extern int uiAlignPanelStep(struct ScrArea *sa, float fac);
+extern int uiAlignPanelStep(struct ScrArea *sa, struct ARegion *ar, float fac);
extern void uiPanelControl(int);
extern void uiSetPanelHandler(int);
@@ -383,6 +381,7 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname);
/* Handlers for regions with UI blocks */
void UI_add_region_handlers(struct ListBase *handlers);
+void UI_add_area_handlers(struct ListBase *handlers);
void UI_add_popup_handlers(struct ListBase *handlers, uiMenuBlockHandle *menu);
/* Module initialization and exit */
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 75526ff8bb4..574cfb11ae5 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -69,7 +69,7 @@
#include "RNA_access.h"
#include "RNA_types.h"
-#include "interface.h"
+#include "interface_intern.h"
/*
* a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt
@@ -86,7 +86,6 @@ static uiFont UIfont[UI_ARRAY]; // no init needed
/* ************* translation ************** */
-/* XXX 2.50 missing from context */
int ui_translate_buttons()
{
return (U.transopts & USER_TR_BUTTONS);
@@ -116,6 +115,12 @@ void ui_block_to_window_fl(const ARegion *ar, uiBlock *block, float *x, float *y
gx= *x;
gy= *y;
+
+ if(block->panel) {
+ gx += block->panel->ofsx;
+ gy += block->panel->ofsy;
+ }
+
*x= ((float)sx) + ((float)getsizex)*(0.5+ 0.5*(gx*block->winmat[0][0]+ gy*block->winmat[1][0]+ block->winmat[3][0]));
*y= ((float)sy) + ((float)getsizey)*(0.5+ 0.5*(gx*block->winmat[0][1]+ gy*block->winmat[1][1]+ block->winmat[3][1]));
}
@@ -170,6 +175,11 @@ void ui_window_to_block_fl(const ARegion *ar, uiBlock *block, float *x, float *y
*y= (a*(py-f) + d*(c-px))/(a*e-d*b);
*x= (px- b*(*y)- c)/a;
+
+ if(block->panel) {
+ *x -= block->panel->ofsx;
+ *y -= block->panel->ofsy;
+ }
}
void ui_window_to_block(const ARegion *ar, uiBlock *block, int *x, int *y)
@@ -482,7 +492,6 @@ void uiEndBlock(const bContext *C, uiBlock *block)
block->auto_open_last= block->oldblock->auto_open_last;
block->tooltipdisabled= block->oldblock->tooltipdisabled;
- uiFreeBlock(C, block->oldblock);
block->oldblock= NULL;
}
@@ -494,34 +503,24 @@ void uiEndBlock(const bContext *C, uiBlock *block)
/* ************** BLOCK DRAWING FUNCTION ************* */
-void uiDrawBlock(uiBlock *block)
+void uiDrawBlock(const bContext *C, uiBlock *block)
{
uiBut *but;
/* we set this only once */
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- /* XXX 2.50 no panels yet */
- //uiPanelPush(block); // panel matrix
- if(block->flag & UI_BLOCK_LOOP) {
+ if(block->flag & UI_BLOCK_LOOP)
uiDrawMenuBox(block->minx, block->miny, block->maxx, block->maxy, block->flag);
- }
- else {
- /* XXX 2.50 no panels yet */
- //if(block->panel) ui_draw_panel(block);
- }
+ else if(block->panel)
+ ui_draw_panel(CTX_wm_region(C), block);
- /* XXX 2.50 need context here? */
- //if(block->drawextra) block->drawextra(curarea, block);
+ if(block->drawextra) block->drawextra(C, block);
for (but= block->buttons.first; but; but= but->next)
ui_draw_but(but);
ui_draw_links(block);
-
- /* XXX 2.50 no panels yet */
- //uiPanelPop(block); // matrix restored
}
/* ************* EVENTS ************* */
@@ -1365,9 +1364,10 @@ void uiFreeBlock(const bContext *C, uiBlock *block)
ui_free_but(C, but);
}
- if(block->panel) block->panel->active= 0;
+ if(block->panel) {
+ block->panel->active= 0;
+ }
BLI_freelistN(&block->saferct);
-
MEM_freeN(block);
}
@@ -1382,6 +1382,24 @@ void uiFreeBlocks(const bContext *C, ListBase *lb)
}
}
+void uiFreeInactiveBlocks(const bContext *C, ListBase *lb)
+{
+ uiBlock *block, *nextblock;
+
+ for(block=lb->first; block; block=nextblock) {
+ nextblock= block->next;
+
+ if(!block->handle) {
+ if(!block->active) {
+ uiFreeBlock(C, block);
+ BLI_remlink(lb, block);
+ }
+ else
+ block->active= 0;
+ }
+ }
+}
+
uiBlock *uiBeginBlock(const bContext *C, ARegion *region, char *name, short dt, short font)
{
ListBase *lb;
@@ -1399,12 +1417,15 @@ uiBlock *uiBeginBlock(const bContext *C, ARegion *region, char *name, short dt,
if (BLI_streq(oldblock->name, name))
break;
- if (oldblock)
- BLI_remlink(lb, oldblock);
+ if (oldblock) {
+ oldblock->active= 0;
+ oldblock->panel= NULL;
+ }
}
block= MEM_callocN(sizeof(uiBlock), "uiBlock");
block->oldblock= oldblock;
+ block->active= 1;
/* at the beginning of the list! for dynamical menus/blocks */
if(lb)
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 1bef11fb47d..39e362ef85a 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -55,7 +55,7 @@
#include "FTF_Api.h"
#endif
-#include "interface.h"
+#include "interface_intern.h"
#define UI_RB_ALPHA 16
static int roundboxtype= 15;
@@ -94,43 +94,43 @@ void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, floa
/* start with corner right-bottom */
if(roundboxtype & 4) {
- glVertex2f( maxx-rad, miny);
+ glVertex2f(maxx-rad, miny);
for(a=0; a<7; a++) {
- glVertex2f( maxx-rad+vec[a][0], miny+vec[a][1]);
+ glVertex2f(maxx-rad+vec[a][0], miny+vec[a][1]);
}
- glVertex2f( maxx, miny+rad);
+ glVertex2f(maxx, miny+rad);
}
- else glVertex2f( maxx, miny);
+ else glVertex2f(maxx, miny);
/* corner right-top */
if(roundboxtype & 2) {
- glVertex2f( maxx, maxy-rad);
+ glVertex2f(maxx, maxy-rad);
for(a=0; a<7; a++) {
- glVertex2f( maxx-vec[a][1], maxy-rad+vec[a][0]);
+ glVertex2f(maxx-vec[a][1], maxy-rad+vec[a][0]);
}
- glVertex2f( maxx-rad, maxy);
+ glVertex2f(maxx-rad, maxy);
}
- else glVertex2f( maxx, maxy);
+ else glVertex2f(maxx, maxy);
/* corner left-top */
if(roundboxtype & 1) {
- glVertex2f( minx+rad, maxy);
+ glVertex2f(minx+rad, maxy);
for(a=0; a<7; a++) {
- glVertex2f( minx+rad-vec[a][0], maxy-vec[a][1]);
+ glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
}
- glVertex2f( minx, maxy-rad);
+ glVertex2f(minx, maxy-rad);
}
- else glVertex2f( minx, maxy);
+ else glVertex2f(minx, maxy);
/* corner left-bottom */
if(roundboxtype & 8) {
- glVertex2f( minx, miny+rad);
+ glVertex2f(minx, miny+rad);
for(a=0; a<7; a++) {
- glVertex2f( minx+vec[a][1], miny+rad-vec[a][0]);
+ glVertex2f(minx+vec[a][1], miny+rad-vec[a][0]);
}
- glVertex2f( minx+rad, miny);
+ glVertex2f(minx+rad, miny);
}
- else glVertex2f( minx, miny);
+ else glVertex2f(minx, miny);
glEnd();
}
@@ -246,7 +246,7 @@ void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy
if(roundboxtype & 2) {
round_box_shade_col(coltop, coldown, (div-rad)/div);
- glVertex2f( maxx, maxy-rad);
+ glVertex2f(maxx, maxy-rad);
for(a=0; a<7; a++) {
round_box_shade_col(coltop, coldown, (div-rad+vec[a][1])/div);
@@ -264,11 +264,11 @@ void gl_round_box_shade(int mode, float minx, float miny, float maxx, float maxy
if(roundboxtype & 1) {
round_box_shade_col(coltop, coldown, 1.0);
- glVertex2f( minx+rad, maxy);
+ 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]);
+ glVertex2f(minx+rad-vec[a][0], maxy-vec[a][1]);
}
round_box_shade_col(coltop, coldown, (div-rad)/div);
@@ -407,6 +407,30 @@ void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, f
glShadeModel(GL_FLAT);
}
+/* plain antialiased unfilled rectangle */
+void uiRoundRect(float minx, float miny, float maxx, float maxy, float rad)
+{
+ float color[4];
+
+ if(roundboxtype & UI_RB_ALPHA) {
+ glGetFloatv(GL_CURRENT_COLOR, color);
+ color[3]= 0.5;
+ glColor4fv(color);
+ glEnable( GL_BLEND );
+ }
+
+ /* set antialias line */
+ if (UI_GetThemeValue(TH_BUT_DRAWTYPE) != TH_MINIMAL) {
+ glEnable( GL_LINE_SMOOTH );
+ glEnable( GL_BLEND );
+ }
+
+ gl_round_box(GL_LINE_LOOP, minx, miny, maxx, maxy, rad);
+
+ glDisable( GL_BLEND );
+ glDisable( GL_LINE_SMOOTH );
+}
+
/* plain fake antialiased unfilled round rectangle */
void uiRoundRectFakeAA(float minx, float miny, float maxx, float maxy, float rad, float asp)
{
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index d7235af14bc..34cce7bf74e 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -51,7 +51,7 @@
#include "UI_interface.h"
#include "UI_text.h"
-#include "interface.h"
+#include "interface_intern.h"
#include "RNA_access.h"
@@ -1417,7 +1417,7 @@ static void ui_blockopen_begin(bContext *C, uiBut *but, uiHandleButtonData *data
}
/* this makes adjacent blocks auto open from now on */
- if(but->block->auto_open==0) but->block->auto_open= 1;
+ //if(but->block->auto_open==0) but->block->auto_open= 1;
}
static void ui_blockopen_end(bContext *C, uiBut *but, uiHandleButtonData *data)
@@ -3568,10 +3568,15 @@ static int ui_handler_region(bContext *C, wmEvent *event, void *userdata)
/* either handle events for already activated button or try to activate */
but= ui_but_find_activated(ar);
- if(but)
- retval= ui_handle_button_event(C, event, but);
- else
- retval= ui_handle_button_over(C, event, ar);
+ if(!but || !button_modal_state(but->active->state))
+ retval= ui_handler_panel_region(C, event);
+
+ if(retval == WM_UI_HANDLER_CONTINUE) {
+ if(but)
+ retval= ui_handle_button_event(C, event, but);
+ else
+ retval= ui_handle_button_over(C, event, ar);
+ }
/* re-enable tooltips */
if(event->type == MOUSEMOVE && (event->x!=event->prevx || event->y!=event->prevy))
diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c
index 5e0c78ebf35..22496513796 100644
--- a/source/blender/editors/interface/interface_icons.c
+++ b/source/blender/editors/interface/interface_icons.c
@@ -61,7 +61,7 @@
// XXX #include "BIF_screen.h"
#include "UI_resources.h" /* elubie: should be removed once the enum for the ICONS is in BIF_preview_icons.h */
-#include "interface.h"
+#include "interface_intern.h"
#include "ED_datafiles.h"
#define ICON_IMAGE_W 512
diff --git a/source/blender/editors/interface/interface.h b/source/blender/editors/interface/interface_intern.h
index 577a374c47d..f4e37867fc3 100644
--- a/source/blender/editors/interface/interface.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -37,6 +37,7 @@ struct ARegion;
struct bContext;
struct IDProperty;
struct uiHandleButtonData;
+struct wmEvent;
struct wmWindow;
/* general defines */
@@ -82,12 +83,6 @@ typedef struct {
} uiIconImage;
typedef struct {
- short mval[2];
- short qual, val;
- int event;
-} uiEvent;
-
-typedef struct {
void *xl, *large, *medium, *small;
} uiFont;
@@ -226,6 +221,9 @@ struct uiBlock {
uiMenuBlockHandle *handle; // handle
int tooltipdisabled; // to avoid tooltip after click
+
+ int handler; // for panels in other windows than buttonswin... just event code
+ int active; // to keep blocks while drawing and free them afterwards
};
typedef struct uiSafetyRct {
@@ -276,12 +274,8 @@ void ui_menu_block_free(struct bContext *C, uiMenuBlockHandle *handle);
void ui_set_name_menu(uiBut *but, int value);
/* interface_panel.c */
-extern void ui_draw_panel(uiBlock *block);
-extern void ui_do_panel(uiBlock *block, uiEvent *uevent);
-extern void ui_scale_panel(uiBlock *block);
-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 shadetop, float shadedown);
-extern void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
+extern int ui_handler_panel_region(struct bContext *C, struct wmEvent *event);
+extern void ui_draw_panel(struct ARegion *ar, uiBlock *block);
/* interface_draw.c */
extern void ui_set_embossfunc(uiBut *but, int drawtype);
@@ -291,6 +285,10 @@ extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
extern void ui_draw_anti_x(float x1, float y1, float x2, float y2);
extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
+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 shadetop, float shadedown);
+extern void gl_round_box_vertical_shade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight);
+
/* interface_handlers.c */
extern void ui_button_active_cancel(const struct bContext *C, uiBut *but);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
new file mode 100644
index 00000000000..fd715cf6c4a
--- /dev/null
+++ b/source/blender/editors/interface/interface_panel.c
@@ -0,0 +1,1610 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+ a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt
+
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "PIL_time.h"
+
+#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
+
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_userdef_types.h"
+
+#include "BKE_context.h"
+#include "BKE_screen.h"
+#include "BKE_utildefines.h"
+
+#include "BIF_gl.h"
+#include "BIF_glutil.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "ED_screen.h"
+
+#include "UI_interface.h"
+#include "UI_text.h"
+#include "UI_view2d.h"
+
+#include "interface_intern.h"
+
+/* Defines */
+
+#define ANIMATION_TIME 0.30
+#define ANIMATION_INTERVAL 0.02
+
+typedef enum uiHandlePanelState {
+ PANEL_STATE_DRAG,
+ PANEL_STATE_DRAG_SCALE,
+ PANEL_STATE_WAIT_UNTAB,
+ PANEL_STATE_ANIMATION,
+ PANEL_STATE_EXIT
+} uiHandlePanelState;
+
+typedef struct uiHandlePanelData {
+ uiHandlePanelState state;
+
+ /* animation */
+ wmTimer *animtimer;
+ double starttime;
+
+ /* dragging */
+ int startx, starty;
+ int startofsx, startofsy;
+ int startsizex, startsizey;
+} uiHandlePanelData;
+
+static void panel_activate_state(bContext *C, Panel *pa, uiHandlePanelState state);
+
+/* ************** panels ************* */
+
+static void copy_panel_offset(Panel *pa, Panel *papar)
+{
+ /* with respect to sizes... papar is parent */
+
+ pa->ofsx= papar->ofsx;
+ pa->ofsy= papar->ofsy + papar->sizey-pa->sizey;
+}
+
+/* global... but will be NULLed after each 'newPanel' call */
+static char *panel_tabbed=NULL, *group_tabbed=NULL;
+
+void uiNewPanelTabbed(char *panelname, char *groupname)
+{
+ panel_tabbed= panelname;
+ group_tabbed= groupname;
+}
+
+/* another global... */
+static int pnl_control= UI_PNL_TRANSP;
+
+void uiPanelControl(int control)
+{
+ pnl_control= control;
+}
+
+/* another global... */
+static int pnl_handler= 0;
+
+void uiSetPanelHandler(int handler)
+{
+ pnl_handler= handler;
+}
+
+/* ofsx/ofsy only used for new panel definitions */
+/* return 1 if visible (create buttons!) */
+int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey)
+{
+ Panel *pa;
+
+ /* check if Panel exists, then use that one */
+ for(pa=ar->panels.first; pa; pa=pa->next)
+ if(strncmp(pa->panelname, panelname, UI_MAX_NAME_STR)==0)
+ if(strncmp(pa->tabname, tabname, UI_MAX_NAME_STR)==0)
+ break;
+
+ if(pa) {
+ /* scale correction */
+ if(pa->control & UI_PNL_SCALE);
+ else {
+ pa->sizex= sizex;
+ if(pa->sizey != sizey) {
+ pa->ofsy+= (pa->sizey - sizey); // check uiNewPanelHeight()
+ pa->sizey= sizey;
+ }
+ }
+ }
+ else {
+ /* new panel */
+ pa= MEM_callocN(sizeof(Panel), "new panel");
+ BLI_addtail(&ar->panels, pa);
+ strncpy(pa->panelname, panelname, UI_MAX_NAME_STR);
+ strncpy(pa->tabname, tabname, UI_MAX_NAME_STR);
+
+ pa->ofsx= ofsx & ~(PNL_GRID-1);
+ pa->ofsy= ofsy & ~(PNL_GRID-1);
+ pa->sizex= sizex;
+ pa->sizey= sizey;
+
+ /* make new Panel tabbed? */
+ if(panel_tabbed && group_tabbed) {
+ Panel *papar;
+ for(papar= ar->panels.first; papar; papar= papar->next) {
+ if(papar->active && papar->paneltab==NULL) {
+ if( strncmp(panel_tabbed, papar->panelname, UI_MAX_NAME_STR)==0) {
+ if( strncmp(group_tabbed, papar->tabname, UI_MAX_NAME_STR)==0) {
+ pa->paneltab= papar;
+ copy_panel_offset(pa, papar);
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ block->panel= pa;
+ block->handler= pnl_handler;
+ pa->active= 1;
+ pa->control= pnl_control;
+
+ /* global control over this feature; UI_PNL_TO_MOUSE only called for hotkey panels */
+ if(U.uiflag & USER_PANELPINNED);
+ else if(pnl_control & UI_PNL_TO_MOUSE) {
+ int mx, my;
+
+ mx= CTX_wm_window(C)->eventstate->x;
+ my= CTX_wm_window(C)->eventstate->y;
+
+ pa->ofsx= mx-pa->sizex/2;
+ pa->ofsy= my-pa->sizey/2;
+
+ if(pa->flag & PNL_CLOSED) pa->flag &= ~PNL_CLOSED;
+ }
+
+ if(pnl_control & UI_PNL_UNSTOW) {
+ if(pa->flag & PNL_CLOSEDY) {
+ pa->flag &= ~PNL_CLOSED;
+ }
+ }
+
+ /* clear ugly globals */
+ panel_tabbed= group_tabbed= NULL;
+ pnl_handler= 0;
+ pnl_control= UI_PNL_TRANSP; // back to default
+
+ if(pa->paneltab) return 0;
+ if(pa->flag & PNL_CLOSED) return 0;
+
+ /* the 'return 0' above makes this to be in end. otherwise closes panels show wrong title */
+ pa->drawname[0]= 0;
+
+ return 1;
+}
+
+void uiFreePanels(ListBase *lb)
+{
+ BLI_freelistN(lb);
+}
+
+void uiNewPanelHeight(uiBlock *block, int sizey)
+{
+ if(sizey<64) sizey= 64;
+
+ if(block->panel) {
+ block->panel->ofsy+= (block->panel->sizey - sizey);
+ block->panel->sizey= sizey;
+ }
+}
+
+void uiNewPanelTitle(uiBlock *block, char *str)
+{
+ if(block->panel)
+ BLI_strncpy(block->panel->drawname, str, UI_MAX_NAME_STR);
+}
+
+static int panel_has_tabs(ARegion *ar, Panel *panel)
+{
+ Panel *pa= ar->panels.first;
+
+ if(panel==NULL) return 0;
+
+ while(pa) {
+ if(pa->active && pa->paneltab==panel) {
+ return 1;
+ }
+ pa= pa->next;
+ }
+ return 0;
+}
+
+static void ui_scale_panel_block(uiBlock *block)
+{
+ uiBut *but;
+ float facx= 1.0, facy= 1.0;
+ int centerx= 0, topy=0, tabsy=0;
+
+ if(block->panel==NULL) return;
+
+ if(block->autofill) ui_autofill(block);
+ /* buttons min/max centered, offset calculated */
+ uiBoundsBlock(block, 0);
+
+ if( block->maxx-block->minx > block->panel->sizex - 2*PNL_SAFETY ) {
+ facx= (block->panel->sizex - (2*PNL_SAFETY))/( block->maxx-block->minx );
+ }
+ else centerx= (block->panel->sizex-( block->maxx-block->minx ) - 2*PNL_SAFETY)/2;
+
+ // tabsy= PNL_HEADER*panel_has_tabs(block->panel);
+ if( (block->maxy-block->miny) > block->panel->sizey - 2*PNL_SAFETY - tabsy) {
+ facy= (block->panel->sizey - (2*PNL_SAFETY) - tabsy)/( block->maxy-block->miny );
+ }
+ else topy= (block->panel->sizey- 2*PNL_SAFETY - tabsy) - ( block->maxy-block->miny ) ;
+
+ but= block->buttons.first;
+ while(but) {
+ but->x1= PNL_SAFETY+centerx+ facx*(but->x1-block->minx);
+ but->y1= PNL_SAFETY+topy + facy*(but->y1-block->miny);
+ but->x2= PNL_SAFETY+centerx+ facx*(but->x2-block->minx);
+ but->y2= PNL_SAFETY+topy + facy*(but->y2-block->miny);
+ if(facx!=1.0) ui_check_but(but); /* for strlen */
+ but= but->next;
+ }
+
+ block->maxx= block->panel->sizex;
+ block->maxy= block->panel->sizey;
+ block->minx= block->miny= 0.0;
+
+}
+
+// for 'home' key
+void uiSetPanelsView2d(ARegion *ar)
+{
+ Panel *pa;
+ uiBlock *block;
+ View2D *v2d;
+ float minx=10000, maxx= -10000, miny=10000, maxy= -10000;
+ int done=0;
+
+ v2d= &ar->v2d;
+
+ for(pa= ar->panels.first; pa; pa=pa->next) {
+ if(pa->active && pa->paneltab==NULL) {
+ done= 1;
+ if(pa->ofsx < minx) minx= pa->ofsx;
+ if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex;
+ if(pa->ofsy < miny) miny= pa->ofsy;
+ if(pa->ofsy+pa->sizey+PNL_HEADER > maxy) maxy= pa->ofsy+pa->sizey+PNL_HEADER;
+ }
+ }
+
+ if(done) {
+ v2d->tot.xmin= minx-PNL_DIST;
+ v2d->tot.xmax= maxx+PNL_DIST;
+ v2d->tot.ymin= miny-PNL_DIST;
+ v2d->tot.ymax= maxy+PNL_DIST;
+ }
+ else {
+ v2d->tot.xmin= 0;
+ v2d->tot.xmax= 1280;
+ v2d->tot.ymin= 0;
+ v2d->tot.ymax= 228;
+
+ /* no panels, but old 'loose' buttons, as in old logic editor */
+ for(block= ar->uiblocks.first; block; block= block->next) {
+ //XXX 2.50 if(block->win==sa->win) {
+ if(block->minx < v2d->tot.xmin) v2d->tot.xmin= block->minx;
+ if(block->maxx > v2d->tot.xmax) v2d->tot.xmax= block->maxx;
+ if(block->miny < v2d->tot.ymin) v2d->tot.ymin= block->miny;
+ if(block->maxy > v2d->tot.ymax) v2d->tot.ymax= block->maxy;
+ //XXX }
+ }
+ }
+}
+
+// make sure the panels are not outside 'tot' area
+void uiMatchPanelsView2d(ARegion *ar)
+{
+ Panel *pa;
+ uiBlock *block;
+ View2D *v2d;
+ int done=0;
+
+ v2d= &ar->v2d;
+
+ for(pa= ar->panels.first; pa; pa=pa->next) {
+ if(pa->active && pa->paneltab==NULL) {
+ done= 1;
+ if(pa->ofsx < v2d->tot.xmin) v2d->tot.xmin= pa->ofsx;
+ if(pa->ofsx+pa->sizex > v2d->tot.xmax)
+ v2d->tot.xmax= pa->ofsx+pa->sizex;
+ if(pa->ofsy < v2d->tot.ymin) v2d->tot.ymin= pa->ofsy;
+ if(pa->ofsy+pa->sizey+PNL_HEADER > v2d->tot.ymax)
+ v2d->tot.ymax= pa->ofsy+pa->sizey+PNL_HEADER;
+ }
+ }
+
+ if(done==0) {
+ /* no panels, but old 'loose' buttons, as in old logic editor */
+ for(block= ar->uiblocks.first; block; block= block->next) {
+ //XXX 2.50 if(block->win==sa->win) {
+ if(block->minx < v2d->tot.xmin) v2d->tot.xmin= block->minx;
+ if(block->maxx > v2d->tot.xmax) v2d->tot.xmax= block->maxx;
+ if(block->miny < v2d->tot.ymin) v2d->tot.ymin= block->miny;
+ if(block->maxy > v2d->tot.ymax) v2d->tot.ymax= block->maxy;
+ //XXX }
+ }
+ }
+}
+
+/* extern used by previewrender */
+void uiPanelPush(uiBlock *block)
+{
+ glPushMatrix();
+
+ if(block->panel)
+ glTranslatef((float)block->panel->ofsx, (float)block->panel->ofsy, 0.0);
+}
+
+void uiPanelPop(uiBlock *block)
+{
+ glPopMatrix();
+}
+
+uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name)
+{
+ uiBlock *block;
+
+ for(block= lb->first; block; block= block->next) {
+ if(block->panel && block->panel->active && block->panel->paneltab==NULL) {
+ if(block->panel->flag & PNL_CLOSED);
+ else if(strncmp(name, block->panel->panelname, UI_MAX_NAME_STR)==0) break;
+ }
+ }
+ return block;
+}
+
+static void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3)
+{
+ // we draw twice, anti polygons not widely supported...
+ glBegin(GL_POLYGON);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x3, y3);
+ glEnd();
+
+ /* set antialias line */
+ glEnable( GL_LINE_SMOOTH );
+ glEnable( GL_BLEND );
+
+ glBegin(GL_LINE_LOOP);
+ glVertex2f(x1, y1);
+ glVertex2f(x2, y2);
+ glVertex2f(x3, y3);
+ glEnd();
+
+ glDisable( GL_LINE_SMOOTH );
+ glDisable( GL_BLEND );
+}
+
+/* triangle 'icon' for panel header */
+void ui_draw_tria_icon(float x, float y, float aspect, char dir)
+{
+ if(dir=='h') {
+ ui_draw_anti_tria( x, y+1, x, y+10.0, x+8, y+6.25);
+ }
+ else {
+ ui_draw_anti_tria( x-2, y+9, x+8-2, y+9, x+4.25-2, y+1);
+ }
+}
+
+void ui_draw_anti_x(float x1, float y1, float x2, float y2)
+{
+
+ /* set antialias line */
+ glEnable( GL_LINE_SMOOTH );
+ glEnable( GL_BLEND );
+
+ glLineWidth(2.0);
+
+ fdrawline(x1, y1, x2, y2);
+ fdrawline(x1, y2, x2, y1);
+
+ glLineWidth(1.0);
+
+ glDisable( GL_LINE_SMOOTH );
+ glDisable( GL_BLEND );
+
+}
+
+/* x 'icon' for panel header */
+static void ui_draw_x_icon(float x, float y)
+{
+ UI_ThemeColor(TH_TEXT_HI);
+
+ ui_draw_anti_x( x, y, x+9.375, y+9.375);
+
+}
+
+#if 0
+static void ui_set_panel_pattern(char dir)
+{
+ static int firsttime= 1;
+ static GLubyte path[4*32], patv[4*32];
+ int a,b,i=0;
+
+ if(firsttime) {
+ firsttime= 0;
+ for(a=0; a<128; a++) patv[a]= 0x33;
+ for(a=0; a<8; a++) {
+ for(b=0; b<4; b++) path[i++]= 0xff; /* 1 scanlines */
+ for(b=0; b<12; b++) path[i++]= 0x0; /* 3 lines */
+ }
+ }
+ glEnable(GL_POLYGON_STIPPLE);
+ if(dir=='h') glPolygonStipple(path);
+ else glPolygonStipple(patv);
+}
+#endif
+
+static char *ui_block_cut_str(uiBlock *block, char *str, short okwidth)
+{
+ short width, ofs=strlen(str);
+ static char str1[128];
+
+ if(ofs>127) return str;
+
+ width= block->aspect*UI_GetStringWidth(block->curfont, str, ui_translate_buttons());
+
+ if(width <= okwidth) return str;
+ strcpy(str1, str);
+
+ while(width > okwidth && ofs>0) {
+ ofs--;
+ str1[ofs]= 0;
+
+ width= block->aspect*UI_GetStringWidth(block->curfont, str1, 0);
+
+ if(width < 10) break;
+ }
+ return str1;
+}
+
+
+#define PNL_ICON 20
+#define PNL_DRAGGER 20
+
+
+static void ui_draw_panel_header(ARegion *ar, uiBlock *block)
+{
+ Panel *pa, *panel= block->panel;
+ float width;
+ int a, nr= 1, pnl_icons;
+ char *activename= panel->drawname[0]?panel->drawname:panel->panelname;
+ char *panelname, *str;
+
+ /* count */
+ for(pa= ar->panels.first; pa; pa=pa->next)
+ if(pa->active)
+ if(pa->paneltab==panel)
+ nr++;
+
+ pnl_icons= PNL_ICON+8;
+ if(panel->control & UI_PNL_CLOSE) pnl_icons+= PNL_ICON;
+
+ if(nr==1) {
+ // full header
+ UI_ThemeColorShade(TH_HEADER, -30);
+ uiSetRoundBox(3);
+ uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+
+ /* active tab */
+ /* draw text label */
+ UI_ThemeColor(TH_TEXT_HI);
+ ui_rasterpos_safe(4.0f+block->minx+pnl_icons, block->maxy+5.0f, block->aspect);
+ UI_DrawString(block->curfont, activename, ui_translate_buttons());
+ return;
+ }
+
+ // tabbed, full header brighter
+ //UI_ThemeColorShade(TH_HEADER, 0);
+ //uiSetRoundBox(3);
+ //uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+
+ a= 0;
+ width= (panel->sizex - 3 - pnl_icons - PNL_ICON)/nr;
+ for(pa= ar->panels.first; pa; pa=pa->next) {
+ panelname= pa->drawname[0]?pa->drawname:pa->panelname;
+ if(a == 0)
+ activename= panelname;
+
+ if(pa->active==0);
+ else if(pa==panel) {
+ /* active tab */
+
+ /* draw the active tab */
+ uiSetRoundBox(3);
+ UI_ThemeColorShade(TH_HEADER, -3);
+ uiRoundBox(2+pnl_icons+a*width, panel->sizey-1, pnl_icons+(a+1)*width, panel->sizey+PNL_HEADER-3, 8);
+
+ /* draw the active text label */
+ UI_ThemeColor(TH_TEXT);
+ ui_rasterpos_safe(16+pnl_icons+a*width, panel->sizey+4, block->aspect);
+ if(panelname != activename && strstr(panelname, activename) == panelname)
+ str= ui_block_cut_str(block, panelname+strlen(activename), (short)(width-10));
+ else
+ str= ui_block_cut_str(block, panelname, (short)(width-10));
+ UI_DrawString(block->curfont, str, ui_translate_buttons());
+
+ a++;
+ }
+ else if(pa->paneltab==panel) {
+ /* draw an inactive tab */
+ uiSetRoundBox(3);
+ UI_ThemeColorShade(TH_HEADER, -60);
+ uiRoundBox(2+pnl_icons+a*width, panel->sizey, pnl_icons+(a+1)*width, panel->sizey+PNL_HEADER-3, 8);
+
+ /* draw an inactive tab label */
+ UI_ThemeColorShade(TH_TEXT_HI, -40);
+ ui_rasterpos_safe(16+pnl_icons+a*width, panel->sizey+4, block->aspect);
+ if(panelname != activename && strstr(panelname, activename) == panelname)
+ str= ui_block_cut_str(block, panelname+strlen(activename), (short)(width-10));
+ else
+ str= ui_block_cut_str(block, panelname, (short)(width-10));
+ UI_DrawString(block->curfont, str, ui_translate_buttons());
+
+ a++;
+ }
+ }
+
+ // dragger
+ /*
+ uiSetRoundBox(15);
+ UI_ThemeColorShade(TH_HEADER, -70);
+ uiRoundBox(panel->sizex-PNL_ICON+5, panel->sizey+5, panel->sizex-5, panel->sizey+PNL_HEADER-5, 5);
+ */
+
+}
+
+static void ui_draw_panel_scalewidget(uiBlock *block)
+{
+ float xmin, xmax, dx;
+ float ymin, ymax, dy;
+
+ xmin= block->maxx-PNL_HEADER+2;
+ xmax= block->maxx-3;
+ ymin= block->miny+3;
+ ymax= block->miny+PNL_HEADER-2;
+
+ dx= 0.5f*(xmax-xmin);
+ dy= 0.5f*(ymax-ymin);
+
+ glEnable(GL_BLEND);
+ glColor4ub(255, 255, 255, 50);
+ fdrawline(xmin, ymin, xmax, ymax);
+ fdrawline(xmin+dx, ymin, xmax, ymax-dy);
+
+ glColor4ub(0, 0, 0, 50);
+ fdrawline(xmin, ymin+block->aspect, xmax, ymax+block->aspect);
+ fdrawline(xmin+dx, ymin+block->aspect, xmax, ymax-dy+block->aspect);
+ glDisable(GL_BLEND);
+}
+
+void ui_draw_panel(ARegion *ar, uiBlock *block)
+{
+ Panel *panel= block->panel;
+ int ofsx;
+ char *panelname= panel->drawname[0]?panel->drawname:panel->panelname;
+
+ if(panel->paneltab) return;
+
+ /* if the panel is minimized vertically:
+ * (------)
+ */
+ if(panel->flag & PNL_CLOSEDY) {
+ /* draw a little rounded box, the size of the header */
+ uiSetRoundBox(15);
+ UI_ThemeColorShade(TH_HEADER, -30);
+ uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+
+ /* title */
+ ofsx= PNL_ICON+8;
+ if(panel->control & UI_PNL_CLOSE) ofsx+= PNL_ICON;
+ UI_ThemeColor(TH_TEXT_HI);
+ ui_rasterpos_safe(4+block->minx+ofsx, block->maxy+5, block->aspect);
+ UI_DrawString(block->curfont, panelname, ui_translate_buttons());
+
+ /* border */
+ if(panel->flag & PNL_SELECT) {
+ UI_ThemeColorShade(TH_HEADER, -120);
+ uiRoundRect(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+ }
+ /* if it's being overlapped by a panel being dragged */
+ if(panel->flag & PNL_OVERLAP) {
+ UI_ThemeColor(TH_TEXT_HI);
+ uiRoundRect(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+ }
+
+ }
+ /* if the panel is minimized horizontally:
+ * /-\
+ * |
+ * |
+ * |
+ * \_/
+ */
+ else if(panel->flag & PNL_CLOSEDX) {
+ char str[4];
+ int a, end, ofs;
+
+ /* draw a little rounded box, the size of the header, rotated 90 deg */
+ uiSetRoundBox(15);
+ UI_ThemeColorShade(TH_HEADER, -30);
+ uiRoundBox(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 8);
+
+ /* title, only the initial character for now */
+ UI_ThemeColor(TH_TEXT_HI);
+ str[1]= 0;
+ end= strlen(panelname);
+ ofs= 20;
+ for(a=0; a<end; a++) {
+ str[0]= panelname[a];
+ if( isupper(str[0]) ) {
+ ui_rasterpos_safe(block->minx+5, block->maxy-ofs, block->aspect);
+ UI_DrawString(block->curfont, str, 0);
+ ofs+= 15;
+ }
+ }
+
+ /* border */
+ if(panel->flag & PNL_SELECT) {
+ UI_ThemeColorShade(TH_HEADER, -120);
+ uiRoundRect(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 8);
+ }
+ if(panel->flag & PNL_OVERLAP) {
+ UI_ThemeColor(TH_TEXT_HI);
+ uiRoundRect(block->minx, block->miny, block->minx+PNL_HEADER, block->maxy+PNL_HEADER, 8);
+ }
+
+ }
+ /* an open panel */
+ else {
+ /* all panels now... */
+ if(panel->control & UI_PNL_SOLID) {
+ UI_ThemeColorShade(TH_HEADER, -30);
+
+ uiSetRoundBox(3);
+ uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+
+ glEnable(GL_BLEND);
+ UI_ThemeColor4(TH_PANEL);
+
+ uiSetRoundBox(12);
+ /* bad code... but its late :) */
+ if(strcmp(block->name, "image_panel_preview")==0)
+ uiRoundRect(block->minx, block->miny, block->maxx, block->maxy, 8);
+ else
+ uiRoundBox(block->minx, block->miny, block->maxx, block->maxy, 8);
+
+ // glRectf(block->minx, block->miny, block->maxx, block->maxy);
+
+ /* shadow */
+ /*
+ glColor4ub(0, 0, 0, 40);
+
+ fdrawline(block->minx+2, block->miny-1, block->maxx+1, block->miny-1);
+ fdrawline(block->maxx+1, block->miny-1, block->maxx+1, block->maxy+7);
+
+ glColor4ub(0, 0, 0, 10);
+
+ fdrawline(block->minx+3, block->miny-2, block->maxx+2, block->miny-2);
+ fdrawline(block->maxx+2, block->miny-2, block->maxx+2, block->maxy+6);
+
+ */
+
+ glDisable(GL_BLEND);
+ }
+ /* floating panel */
+ else if(panel->control & UI_PNL_TRANSP) {
+ UI_ThemeColorShade(TH_HEADER, -30);
+ uiSetRoundBox(3);
+ uiRoundBox(block->minx, block->maxy, block->maxx, block->maxy+PNL_HEADER, 8);
+
+ glEnable(GL_BLEND);
+ UI_ThemeColor4(TH_PANEL);
+ glRectf(block->minx, block->miny, block->maxx, block->maxy);
+
+ glDisable(GL_BLEND);
+ }
+
+ /* draw the title, tabs, etc in the header */
+ ui_draw_panel_header(ar, block);
+
+ /* in some occasions, draw a border */
+ if(panel->flag & PNL_SELECT) {
+ if(panel->control & UI_PNL_SOLID) uiSetRoundBox(15);
+ else uiSetRoundBox(3);
+
+ UI_ThemeColorShade(TH_HEADER, -120);
+ uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 8);
+ }
+ if(panel->flag & PNL_OVERLAP) {
+ if(panel->control & UI_PNL_SOLID) uiSetRoundBox(15);
+ else uiSetRoundBox(3);
+
+ UI_ThemeColor(TH_TEXT_HI);
+ uiRoundRect(block->minx, block->miny, block->maxx, block->maxy+PNL_HEADER, 8);
+ }
+
+ if(panel->control & UI_PNL_SCALE)
+ ui_draw_panel_scalewidget(block);
+
+ /* and a soft shadow-line for now */
+ /*
+ glEnable( GL_BLEND );
+ glColor4ub(0, 0, 0, 50);
+ fdrawline(block->maxx, block->miny, block->maxx, block->maxy+PNL_HEADER/2);
+ fdrawline(block->minx, block->miny, block->maxx, block->miny);
+ glDisable(GL_BLEND);
+ */
+
+ }
+
+ /* draw optional close icon */
+
+ ofsx= 6;
+ if(panel->control & UI_PNL_CLOSE) {
+
+ ui_draw_x_icon(block->minx+2+ofsx, block->maxy+5);
+ ofsx= 22;
+ }
+
+ /* draw collapse icon */
+
+ UI_ThemeColor(TH_TEXT_HI);
+
+ if(panel->flag & PNL_CLOSEDY)
+ ui_draw_tria_icon(block->minx+6+ofsx, block->maxy+5, block->aspect, 'h');
+ else if(panel->flag & PNL_CLOSEDX)
+ ui_draw_tria_icon(block->minx+7, block->maxy+2, block->aspect, 'h');
+ else
+ ui_draw_tria_icon(block->minx+6+ofsx, block->maxy+5, block->aspect, 'v');
+}
+
+/* ------------ panel alignment ---------------- */
+
+
+/* this function is needed because uiBlock and Panel itself dont
+change sizey or location when closed */
+static int get_panel_real_ofsy(Panel *pa)
+{
+ if(pa->flag & PNL_CLOSEDY) return pa->ofsy+pa->sizey;
+ else if(pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDY)) return pa->ofsy+pa->sizey;
+ else return pa->ofsy;
+}
+
+static int get_panel_real_ofsx(Panel *pa)
+{
+ if(pa->flag & PNL_CLOSEDX) return pa->ofsx+PNL_HEADER;
+ else if(pa->paneltab && (pa->paneltab->flag & PNL_CLOSEDX)) return pa->ofsx+PNL_HEADER;
+ else return pa->ofsx+pa->sizex;
+}
+
+
+typedef struct PanelSort {
+ Panel *pa, *orig;
+} PanelSort;
+
+/* note about sorting;
+ the sortcounter has a lower value for new panels being added.
+ however, that only works to insert a single panel, when more new panels get
+ added the coordinates of existing panels and the previously stored to-be-insterted
+ panels do not match for sorting */
+
+static int find_leftmost_panel(const void *a1, const void *a2)
+{
+ const PanelSort *ps1=a1, *ps2=a2;
+
+ if( ps1->pa->ofsx > ps2->pa->ofsx) return 1;
+ else if( ps1->pa->ofsx < ps2->pa->ofsx) return -1;
+ else if( ps1->pa->sortcounter > ps2->pa->sortcounter) return 1;
+ else if( ps1->pa->sortcounter < ps2->pa->sortcounter) return -1;
+
+ return 0;
+}
+
+
+static int find_highest_panel(const void *a1, const void *a2)
+{
+ const PanelSort *ps1=a1, *ps2=a2;
+
+ if( ps1->pa->ofsy < ps2->pa->ofsy) return 1;
+ else if( ps1->pa->ofsy > ps2->pa->ofsy) return -1;
+ else if( ps1->pa->sortcounter > ps2->pa->sortcounter) return 1;
+ else if( ps1->pa->sortcounter < ps2->pa->sortcounter) return -1;
+
+ return 0;
+}
+
+/* this doesnt draw */
+/* returns 1 when it did something */
+int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac)
+{
+ SpaceButs *sbuts= sa->spacedata.first;
+ Panel *pa;
+ PanelSort *ps, *panelsort, *psnext;
+ static int sortcounter= 0;
+ int a, tot=0, done;
+
+ if(sa->spacetype!=SPACE_BUTS)
+ return 0;
+
+ /* count active, not tabbed Panels */
+ for(pa= ar->panels.first; pa; pa= pa->next) {
+ if(pa->active && pa->paneltab==NULL) tot++;
+ }
+
+ if(tot==0) return 0;
+
+ /* extra; change close direction? */
+ for(pa= ar->panels.first; pa; pa= pa->next) {
+ if(pa->active && pa->paneltab==NULL) {
+ if( (pa->flag & PNL_CLOSEDX) && (sbuts->align==BUT_VERTICAL) )
+ pa->flag ^= PNL_CLOSED;
+
+ else if( (pa->flag & PNL_CLOSEDY) && (sbuts->align==BUT_HORIZONTAL) )
+ pa->flag ^= PNL_CLOSED;
+
+ }
+ }
+
+ panelsort= MEM_callocN( tot*sizeof(PanelSort), "panelsort");
+
+ /* fill panelsort array */
+ ps= panelsort;
+ for(pa= ar->panels.first; pa; pa= pa->next) {
+ if(pa->active && pa->paneltab==NULL) {
+ ps->pa= MEM_dupallocN(pa);
+ ps->orig= pa;
+ ps++;
+ }
+ }
+
+ if(sbuts->align==BUT_VERTICAL)
+ qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel);
+ else
+ qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel);
+
+ /* no smart other default start loc! this keeps switching f5/f6/etc compatible */
+ ps= panelsort;
+ ps->pa->ofsx= 0;
+ ps->pa->ofsy= 0;
+
+ for(a=0 ; a<tot-1; a++, ps++) {
+ psnext= ps+1;
+
+ if(sbuts->align==BUT_VERTICAL) {
+ psnext->pa->ofsx = ps->pa->ofsx;
+ psnext->pa->ofsy = get_panel_real_ofsy(ps->pa) - psnext->pa->sizey-PNL_HEADER-PNL_DIST;
+ }
+ else {
+ psnext->pa->ofsx = get_panel_real_ofsx(ps->pa)+PNL_DIST;
+ psnext->pa->ofsy = ps->pa->ofsy + ps->pa->sizey - psnext->pa->sizey;
+ }
+ }
+
+ /* we interpolate */
+ done= 0;
+ ps= panelsort;
+ for(a=0; a<tot; a++, ps++) {
+ if((ps->pa->flag & PNL_SELECT)==0) {
+ if((ps->orig->ofsx != ps->pa->ofsx) || (ps->orig->ofsy != ps->pa->ofsy)) {
+ ps->orig->ofsx= floor(0.5 + fac*ps->pa->ofsx + (1.0-fac)*ps->orig->ofsx);
+ ps->orig->ofsy= floor(0.5 + fac*ps->pa->ofsy + (1.0-fac)*ps->orig->ofsy);
+ done= 1;
+ }
+ }
+ }
+
+ /* copy locations to tabs */
+ for(pa= ar->panels.first; pa; pa= pa->next) {
+ if(pa->paneltab && pa->active) {
+ copy_panel_offset(pa, pa->paneltab);
+ }
+ }
+
+ /* set counter, used for sorting with newly added panels */
+ sortcounter++;
+ for(pa= ar->panels.first; pa; pa= pa->next)
+ if(pa->active)
+ pa->sortcounter= sortcounter;
+
+ /* free panelsort array */
+ for(ps= panelsort, a=0; a<tot; a++, ps++)
+ MEM_freeN(ps->pa);
+ MEM_freeN(panelsort);
+
+ return done;
+}
+
+
+static void ui_do_animate(bContext *C, Panel *panel)
+{
+ uiHandlePanelData *data= panel->activedata;
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= CTX_wm_region(C);
+ float fac;
+
+ fac= (PIL_check_seconds_timer()-data->starttime)/ANIMATION_TIME;
+ fac= sqrt(fac);
+ fac= MIN2(fac, 1.0f);
+
+ /* for max 1 second, interpolate positions */
+ if(uiAlignPanelStep(sa, ar, fac))
+ ED_region_tag_redraw(ar);
+ else
+ fac= 1.0f;
+
+ if(fac == 1.0f) {
+ panel_activate_state(C, panel, PANEL_STATE_EXIT);
+ return;
+ }
+}
+
+/* only draws blocks with panels */
+void uiDrawPanels(const bContext *C, int re_align)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= CTX_wm_region(C);
+ uiBlock *block;
+ Panel *panot, *panew, *patest;
+
+ /* scaling contents */
+ for(block= ar->uiblocks.first; block; block= block->next)
+ if(block->active && block->panel)
+ ui_scale_panel_block(block);
+
+ /* consistancy; are panels not made, whilst they have tabs */
+ for(panot= ar->panels.first; panot; panot= panot->next) {
+ if(panot->active==0) { // not made
+
+ for(panew= ar->panels.first; panew; panew= panew->next) {
+ if(panew->active) {
+ if(panew->paneltab==panot) { // panew is tab in notmade pa
+ break;
+ }
+ }
+ }
+ /* now panew can become the new parent, check all other tabs */
+ if(panew) {
+ for(patest= ar->panels.first; patest; patest= patest->next) {
+ if(patest->paneltab == panot) {
+ patest->paneltab= panew;
+ }
+ }
+ panot->paneltab= panew;
+ panew->paneltab= NULL;
+ ED_region_tag_redraw(ar); // the buttons panew were not made
+ }
+ }
+ }
+
+ /* re-align */
+ if(re_align) uiAlignPanelStep(sa, ar, 1.0);
+
+ if(sa->spacetype!=SPACE_BUTS) {
+ SpaceLink *sl= sa->spacedata.first;
+ for(block= ar->uiblocks.first; block; block= block->next) {
+ if(block->active && block->panel && block->panel->active && block->panel->paneltab == NULL) {
+ float dx=0.0, dy=0.0, minx, miny, maxx, maxy, miny_panel;
+
+ minx= sl->blockscale*block->panel->ofsx;
+ maxx= sl->blockscale*(block->panel->ofsx+block->panel->sizex);
+ miny= sl->blockscale*(block->panel->ofsy+block->panel->sizey);
+ maxy= sl->blockscale*(block->panel->ofsy+block->panel->sizey+PNL_HEADER);
+ miny_panel= sl->blockscale*(block->panel->ofsy);
+
+ /* check to see if snapped panels have been left out in the open by resizing a window
+ * and if so, offset them back to where they belong */
+ if (block->panel->snap) {
+ if (((block->panel->snap) & PNL_SNAP_RIGHT) &&
+ (maxx < (float)sa->winx)) {
+
+ dx = sa->winx-maxx;
+ block->panel->ofsx+= dx/sl->blockscale;
+ }
+ if (((block->panel->snap) & PNL_SNAP_TOP) &&
+ (maxy < (float)sa->winy)) {
+
+ dy = sa->winy-maxy;
+ block->panel->ofsy+= dy/sl->blockscale;
+ }
+
+ /* reset these vars with updated panel offset distances */
+ minx= sl->blockscale*block->panel->ofsx;
+ maxx= sl->blockscale*(block->panel->ofsx+block->panel->sizex);
+ miny= sl->blockscale*(block->panel->ofsy+block->panel->sizey);
+ maxy= sl->blockscale*(block->panel->ofsy+block->panel->sizey+PNL_HEADER);
+ miny_panel= sl->blockscale*(block->panel->ofsy);
+ } else
+ /* reset to no snapping */
+ block->panel->snap = PNL_SNAP_NONE;
+
+
+ /* clip panels (headers) for non-butspace situations (maybe make optimized event later) */
+
+ /* check left and right edges */
+ if (minx < PNL_SNAP_DIST) {
+ dx = -minx;
+ block->panel->snap |= PNL_SNAP_LEFT;
+ }
+ else if (maxx > ((float)sa->winx - PNL_SNAP_DIST)) {
+ dx= sa->winx-maxx;
+ block->panel->snap |= PNL_SNAP_RIGHT;
+ }
+ if( minx + dx < 0.0) dx= -minx; // when panel cant fit, put it fixed here
+
+ /* check top and bottom edges */
+ if ((miny_panel < PNL_SNAP_DIST) && (miny_panel > -PNL_SNAP_DIST)) {
+ dy= -miny_panel;
+ block->panel->snap |= PNL_SNAP_BOTTOM;
+ }
+ if(miny < PNL_SNAP_DIST) {
+ dy= -miny;
+ block->panel->snap |= PNL_SNAP_BOTTOM;
+ }
+ else if(maxy > ((float)sa->winy - PNL_SNAP_DIST)) {
+ dy= sa->winy-maxy;
+ block->panel->snap |= PNL_SNAP_TOP;
+ }
+ if( miny + dy < 0.0) dy= -miny; // when panel cant fit, put it fixed here
+
+
+ block->panel->ofsx+= dx/sl->blockscale;
+ block->panel->ofsy+= dy/sl->blockscale;
+
+ /* copy locations */
+ for(patest= ar->panels.first; patest; patest= patest->next) {
+ if(patest->paneltab==block->panel) copy_panel_offset(patest, block->panel);
+ }
+
+ }
+ }
+ }
+
+ /* draw panels, selected on top */
+ for(block= ar->uiblocks.first; block; block=block->next) {
+ if(block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
+ uiPanelPush(block);
+ uiDrawBlock(C, block);
+ uiPanelPop(block);
+ }
+ }
+
+ for(block= ar->uiblocks.first; block; block=block->next) {
+ if(block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
+ uiPanelPush(block);
+ uiDrawBlock(C, block);
+ uiPanelPop(block);
+ }
+ }
+}
+
+/* ------------ panel merging ---------------- */
+
+static void check_panel_overlap(ARegion *ar, Panel *panel)
+{
+ Panel *pa;
+
+ /* also called with panel==NULL for clear */
+
+ for(pa=ar->panels.first; pa; pa=pa->next) {
+ pa->flag &= ~PNL_OVERLAP;
+ if(panel && (pa != panel)) {
+ if(pa->paneltab==NULL && pa->active) {
+ float safex= 0.2, safey= 0.2;
+
+ if( pa->flag & PNL_CLOSEDX) safex= 0.05;
+ else if(pa->flag & PNL_CLOSEDY) safey= 0.05;
+ else if( panel->flag & PNL_CLOSEDX) safex= 0.05;
+ else if(panel->flag & PNL_CLOSEDY) safey= 0.05;
+
+ if( pa->ofsx > panel->ofsx- safex*panel->sizex)
+ if( pa->ofsx+pa->sizex < panel->ofsx+ (1.0+safex)*panel->sizex)
+ if( pa->ofsy > panel->ofsy- safey*panel->sizey)
+ if( pa->ofsy+pa->sizey < panel->ofsy+ (1.0+safey)*panel->sizey)
+ pa->flag |= PNL_OVERLAP;
+ }
+ }
+ }
+}
+
+static void test_add_new_tabs(ARegion *ar)
+{
+ Panel *pa, *pasel=NULL, *palap=NULL;
+ /* search selected and overlapped panel */
+
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa->active) {
+ if(pa->flag & PNL_SELECT) pasel= pa;
+ if(pa->flag & PNL_OVERLAP) palap= pa;
+ }
+ pa= pa->next;
+ }
+
+ if(pasel && palap==NULL) {
+
+ /* copy locations */
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa->paneltab==pasel) {
+ copy_panel_offset(pa, pasel);
+ }
+ pa= pa->next;
+ }
+ }
+
+ if(pasel==NULL || palap==NULL) return;
+
+ /* the overlapped panel becomes a tab */
+ palap->paneltab= pasel;
+
+ /* the selected panel gets coords of overlapped one */
+ copy_panel_offset(pasel, palap);
+
+ /* and its tabs */
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa->paneltab == pasel) {
+ copy_panel_offset(pa, palap);
+ }
+ pa= pa->next;
+ }
+
+ /* but, the overlapped panel already can have tabs too! */
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa->paneltab == palap) {
+ pa->paneltab = pasel;
+ }
+ pa= pa->next;
+ }
+}
+
+/* ------------ panel drag ---------------- */
+
+static void ui_do_drag(bContext *C, wmEvent *event, Panel *panel)
+{
+ uiHandlePanelData *data= panel->activedata;
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= CTX_wm_region(C);
+ short align=0, dx=0, dy=0;
+
+ /* first clip for window, no dragging outside */
+ if(!BLI_in_rcti(&ar->winrct, event->x, event->y))
+ return;
+
+ if(sa->spacetype==SPACE_BUTS) {
+ SpaceButs *sbuts= sa->spacedata.first;
+ align= sbuts->align;
+ }
+
+ dx= (event->x-data->startx) & ~(PNL_GRID-1);
+ dy= (event->y-data->starty) & ~(PNL_GRID-1);
+
+ if(data->state == PANEL_STATE_DRAG_SCALE) {
+ panel->sizex = MAX2(data->startsizex+dx, UI_PANEL_MINX);
+
+ if(data->startsizey-dy < UI_PANEL_MINY) {
+ dy= -UI_PANEL_MINY+data->startsizey;
+ }
+ panel->sizey = data->startsizey-dy;
+
+ panel->ofsy= data->startofsy+dy;
+
+ }
+ else {
+ /* reset the panel snapping, to allow dragging away from snapped edges */
+ panel->snap = PNL_SNAP_NONE;
+
+ panel->ofsx = data->startofsx+dx;
+ panel->ofsy = data->startofsy+dy;
+ check_panel_overlap(ar, panel);
+
+ if(align) uiAlignPanelStep(sa, ar, 0.2);
+ }
+
+ ED_region_tag_redraw(ar);
+}
+
+static void ui_do_untab(bContext *C, wmEvent *event, Panel *panel)
+{
+ uiHandlePanelData *data= panel->activedata;
+ ARegion *ar= CTX_wm_region(C);
+ Panel *pa, *panew= NULL;
+ int nr;
+
+ /* wait until a threshold is passed to untab */
+ if(abs(event->x-data->startx) + abs(event->y-data->starty) > 6) {
+ /* find new parent panel */
+ nr= 0;
+ for(pa= ar->panels.first; pa; pa=pa->next) {
+ if(pa->paneltab==panel) {
+ panew= pa;
+ nr++;
+ }
+ }
+
+ /* make old tabs point to panew */
+ panew->paneltab= NULL;
+
+ for(pa= ar->panels.first; pa; pa=pa->next)
+ if(pa->paneltab==panel)
+ pa->paneltab= panew;
+
+ panel_activate_state(C, panel, PANEL_STATE_DRAG);
+ }
+}
+
+/* region level panel interaction */
+
+static void panel_clicked_tabs(bContext *C, ScrArea *sa, ARegion *ar, uiBlock *block, int mousex)
+{
+ Panel *pa, *tabsel=NULL, *panel= block->panel;
+ int nr= 1, a, width, ofsx;
+
+ ofsx= PNL_ICON;
+ if(block->panel->control & UI_PNL_CLOSE) ofsx+= PNL_ICON;
+
+ /* count */
+ for(pa= ar->panels.first; pa; pa=pa->next)
+ if(pa!=panel)
+ if(pa->active && pa->paneltab==panel)
+ nr++;
+
+ if(nr==1) return;
+
+ /* find clicked tab, mouse in panel coords */
+ a= 0;
+ width= (int)((float)(panel->sizex - ofsx-10)/nr);
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa==panel || (pa->active && pa->paneltab==panel)) {
+ if( (mousex > ofsx+a*width) && (mousex < ofsx+(a+1)*width) ) {
+ tabsel= pa;
+ break;
+ }
+ a++;
+ }
+ pa= pa->next;
+ }
+
+ if(tabsel) {
+ if(tabsel == panel) {
+ panel_activate_state(C, panel, PANEL_STATE_WAIT_UNTAB);
+ }
+ else {
+ /* tabsel now becomes parent for all others */
+ panel->paneltab= tabsel;
+ tabsel->paneltab= NULL;
+
+ pa= ar->panels.first;
+ while(pa) {
+ if(pa->paneltab == panel) pa->paneltab = tabsel;
+ pa= pa->next;
+ }
+
+ /* panels now differ size.. */
+ if(sa->spacetype==SPACE_BUTS) {
+ SpaceButs *sbuts= sa->spacedata.first;
+ if(sbuts->align)
+ uiAlignPanelStep(sa, ar, 1.0);
+ }
+
+ ED_region_tag_redraw(ar);
+ }
+ }
+
+}
+
+/* this function is supposed to call general window drawing too */
+/* also it supposes a block has panel, and isnt a menu */
+static void ui_handle_panel_header(bContext *C, uiBlock *block, int mx, int my)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= CTX_wm_region(C);
+ Panel *pa;
+ int align= 0, button= 0;
+
+ if(sa->spacetype==SPACE_BUTS) {
+ SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
+ align= sbuts->align;
+ }
+
+ /* mouse coordinates in panel space! */
+
+ /* check open/collapsed button */
+ if(block->panel->flag & PNL_CLOSEDX) {
+ if(my >= block->maxy) button= 1;
+ }
+ else if(block->panel->control & UI_PNL_CLOSE) {
+ if(mx <= block->minx+PNL_ICON-2) button= 2;
+ else if(mx <= block->minx+2*PNL_ICON+2) button= 1;
+ }
+ else if(mx <= block->minx+PNL_ICON+2) {
+ button= 1;
+ }
+
+ if(button) {
+ if(button==2) { // close
+ //XXX 2.50 rem_blockhandler(sa, block->handler);
+ ED_region_tag_redraw(ar);
+ }
+ else { // collapse
+ if(block->panel->flag & PNL_CLOSED) {
+ block->panel->flag &= ~PNL_CLOSED;
+ /* snap back up so full panel aligns with screen edge */
+ if (block->panel->snap & PNL_SNAP_BOTTOM)
+ block->panel->ofsy= 0;
+ }
+ else if(align==BUT_HORIZONTAL) {
+ block->panel->flag |= PNL_CLOSEDX;
+ }
+ else {
+ /* snap down to bottom screen edge*/
+ block->panel->flag |= PNL_CLOSEDY;
+ if (block->panel->snap & PNL_SNAP_BOTTOM)
+ block->panel->ofsy= -block->panel->sizey;
+ }
+
+ for(pa= ar->panels.first; pa; pa= pa->next) {
+ if(pa->paneltab==block->panel) {
+ if(block->panel->flag & PNL_CLOSED) pa->flag |= PNL_CLOSED;
+ else pa->flag &= ~PNL_CLOSED;
+ }
+ }
+ }
+
+ if(align)
+ panel_activate_state(C, block->panel, PANEL_STATE_ANIMATION);
+ else
+ ED_region_tag_redraw(ar);
+ }
+ else if(block->panel->flag & PNL_CLOSED) {
+ panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
+ }
+ /* check if clicked in tabbed area */
+ else if(mx < block->maxx-PNL_ICON-3 && panel_has_tabs(ar, block->panel)) {
+ panel_clicked_tabs(C, sa, ar, block, mx);
+ }
+ else {
+ panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
+ }
+}
+
+int ui_handler_panel_region(bContext *C, wmEvent *event)
+{
+ ScrArea *sa= CTX_wm_area(C);
+ ARegion *ar= CTX_wm_region(C);
+ uiBlock *block;
+ int retval, mx, my, inside_header= 0, inside_scale= 0;
+
+ retval= WM_UI_HANDLER_CONTINUE;
+
+ for(block=ar->uiblocks.last; block; block=block->prev) {
+ mx= event->x;
+ my= event->y;
+ ui_window_to_block(ar, block, &mx, &my);
+
+ /* check if inside boundbox */
+ if(block->panel && block->panel->paneltab==NULL)
+ if(block->minx <= mx && block->maxx >= mx)
+ if(block->miny <= my && block->maxy+PNL_HEADER >= my)
+ break;
+ }
+
+ if(!block)
+ return retval;
+
+ /* clicked at panel header? */
+ if(block->panel->flag & PNL_CLOSEDX) {
+ if(block->minx <= mx && block->minx+PNL_HEADER >= mx)
+ inside_header= 1;
+ }
+ else if((block->maxy <= my) && (block->maxy+PNL_HEADER >= my)) {
+ inside_header= 1;
+ }
+ else if(block->panel->control & UI_PNL_SCALE) {
+ if(block->maxx-PNL_HEADER <= mx)
+ if(block->miny+PNL_HEADER >= my)
+ inside_scale= 1;
+ }
+
+ if(!event->val)
+ return retval;
+
+ if(event->type == LEFTMOUSE) {
+ if(inside_header)
+ ui_handle_panel_header(C, block, mx, my);
+ else if(inside_scale && !(block->panel->flag & PNL_CLOSED))
+ panel_activate_state(C, block->panel, PANEL_STATE_DRAG_SCALE);
+ }
+ else if(event->type == ESCKEY) {
+ /*XXX 2.50 if(block->handler) {
+ rem_blockhandler(sa, block->handler);
+ ED_region_tag_redraw(ar);
+ retval= WM_UI_HANDLER_BREAK;
+ }*/
+ }
+ else if(event->type==PADPLUSKEY || event->type==PADMINUS) {
+ int zoom=0;
+
+ /* if panel is closed, only zoom if mouse is over the header */
+ if (block->panel->flag & (PNL_CLOSEDX|PNL_CLOSEDY)) {
+ if (inside_header)
+ zoom=1;
+ }
+ else
+ zoom=1;
+
+ if(zoom) {
+ SpaceLink *sl= sa->spacedata.first;
+
+ if(sa->spacetype!=SPACE_BUTS) {
+ if(!(block->panel->control & UI_PNL_SCALE)) {
+ if(event->type==PADPLUSKEY) sl->blockscale+= 0.1;
+ else sl->blockscale-= 0.1;
+ CLAMP(sl->blockscale, 0.6, 1.0);
+
+ ED_region_tag_redraw(ar);
+ retval= WM_UI_HANDLER_BREAK;
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
+/* window level modal panel interaction */
+
+static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
+{
+ Panel *panel= userdata;
+ uiHandlePanelData *data= panel->activedata;
+
+ /* verify if we can stop */
+ if(event->type == LEFTMOUSE && !event->val) {
+ panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
+ return WM_UI_HANDLER_BREAK;
+ }
+ else if(event->type == MOUSEMOVE) {
+ if(data->state == PANEL_STATE_WAIT_UNTAB)
+ ui_do_untab(C, event, panel);
+ else if(data->state == PANEL_STATE_DRAG)
+ ui_do_drag(C, event, panel);
+ }
+ else if(event->type == TIMER && event->customdata == data->animtimer) {
+ if(data->state == PANEL_STATE_ANIMATION)
+ ui_do_animate(C, panel);
+ else if(data->state == PANEL_STATE_DRAG)
+ ui_do_drag(C, event, panel);
+ }
+
+ if(data->state == PANEL_STATE_ANIMATION)
+ return WM_UI_HANDLER_CONTINUE;
+ else
+ return WM_UI_HANDLER_BREAK;
+}
+
+static void ui_handler_remove_panel(bContext *C, void *userdata)
+{
+ Panel *pa= userdata;
+
+ panel_activate_state(C, pa, PANEL_STATE_EXIT);
+}
+
+static void panel_activate_state(bContext *C, Panel *pa, uiHandlePanelState state)
+{
+ uiHandlePanelData *data= pa->activedata;
+ wmWindow *win= CTX_wm_window(C);
+ ARegion *ar= CTX_wm_region(C);
+
+ if(data && data->state == state)
+ return;
+
+ if(state == PANEL_STATE_EXIT || state == PANEL_STATE_ANIMATION) {
+ if(data && data->state != PANEL_STATE_ANIMATION) {
+ test_add_new_tabs(ar); // also copies locations of tabs in dragged panel
+ check_panel_overlap(ar, NULL); // clears
+ }
+
+ pa->flag &= ~PNL_SELECT;
+ }
+ else
+ pa->flag |= PNL_SELECT;
+
+ if(data && data->animtimer) {
+ WM_event_remove_window_timer(win, data->animtimer);
+ data->animtimer= NULL;
+ }
+
+ if(state == PANEL_STATE_EXIT) {
+ MEM_freeN(data);
+ pa->activedata= NULL;
+
+ WM_event_remove_ui_handler(&win->handlers, ui_handler_panel, ui_handler_remove_panel, pa);
+ }
+ else {
+ if(!data) {
+ data= MEM_callocN(sizeof(uiHandlePanelData), "uiHandlePanelData");
+ pa->activedata= data;
+
+ WM_event_add_ui_handler(C, &win->handlers, ui_handler_panel, ui_handler_remove_panel, pa);
+ }
+
+ if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
+ data->animtimer= WM_event_add_window_timer(win, ANIMATION_INTERVAL);
+
+ data->state= state;
+ data->startx= win->eventstate->x;
+ data->starty= win->eventstate->y;
+ data->startofsx= pa->ofsx;
+ data->startofsy= pa->ofsy;
+ data->startsizex= pa->sizex;
+ data->startsizey= pa->sizey;
+ data->starttime= PIL_check_seconds_timer();
+ }
+
+ ED_region_tag_redraw(ar);
+
+ /* XXX exception handling, 3d window preview panel */
+ /* if(block->drawextra==BIF_view3d_previewdraw)
+ BIF_view3d_previewrender_clear(curarea);*/
+
+ /* XXX exception handling, 3d window preview panel */
+ /* if(block->drawextra==BIF_view3d_previewdraw)
+ BIF_view3d_previewrender_signal(curarea, PR_DISPRECT);
+ else if(strcmp(block->name, "image_panel_preview")==0)
+ image_preview_event(2); */
+}
+
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index dca77b94a14..0009f301b63 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -54,7 +54,7 @@
#include "ED_screen.h"
-#include "interface.h"
+#include "interface_intern.h"
#define MENU_BUTTON_HEIGHT 20
#define B_NOP -1
@@ -306,7 +306,7 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
static ARegionType type;
ARegion *ar;
uiTooltipData *data;
- int x1, x2, y1, y2, winx, winy;
+ int x1, x2, y1, y2, winx, winy, ofsx, ofsy;
if(!but->tip || strlen(but->tip)==0)
return NULL;
@@ -329,9 +329,12 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but)
ar->regiondata= data;
/* compute position */
- x1= (but->x1+but->x2)/2;
+ ofsx= (but->block->panel)? but->block->panel->ofsx: 0;
+ ofsy= (but->block->panel)? but->block->panel->ofsy: 0;
+
+ x1= (but->x1+but->x2)/2 + ofsx;
x2= x1+but->aspect*((data->bbox.xmax-data->bbox.xmin) + 8);
- y2= but->y1-10;
+ y2= but->y1-10 + ofsy;
y1= y2-but->aspect*((data->bbox.ymax+(data->bbox.ymax-data->bbox.ymin)));
y2 += 8;
@@ -612,7 +615,7 @@ static void ui_block_region_draw(const bContext *C, ARegion *ar)
uiBlock *block;
for(block=ar->uiblocks.first; block; block=block->next)
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
uiMenuBlockHandle *ui_menu_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockFuncFP block_func, void *arg)
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index 2398f8e2e35..474d057beea 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -53,7 +53,7 @@
#include "UI_view2d.h"
#include "UI_interface.h"
-#include "interface.h"
+#include "interface_intern.h"
/* *********************************************************************** */
/* Refresh and Validation */
diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c
index b50af152922..3c5c72cda5f 100644
--- a/source/blender/editors/screen/area.c
+++ b/source/blender/editors/screen/area.c
@@ -205,6 +205,8 @@ void ED_region_do_draw(bContext *C, ARegion *ar)
if(sa)
region_draw_emboss(ar);
+
+ uiFreeInactiveBlocks(C, &ar->uiblocks);
/* XXX test: add convention to end regions always in pixel space, for drawing of borders/gestures etc */
ED_region_pixelspace(ar);
@@ -524,7 +526,6 @@ void ED_region_init(bContext *C, ARegion *ar)
/* area vertices were set */
void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
{
- Panel *pa1, *pa2, *patab;
ARegion *ar;
sa1->headertype= sa2->headertype;
@@ -542,24 +543,6 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
BKE_spacedata_copylist(&sa1->spacedata, &sa2->spacedata);
}
- BLI_freelistN(&sa1->panels);
- BLI_duplicatelist(&sa1->panels, &sa2->panels);
-
- /* copy panel pointers */
- for(pa1= sa1->panels.first; pa1; pa1= pa1->next) {
-
- patab= sa1->panels.first;
- pa2= sa2->panels.first;
- while(patab) {
- if( pa1->paneltab == pa2) {
- pa1->paneltab = patab;
- break;
- }
- patab= patab->next;
- pa2= pa2->next;
- }
- }
-
/* regions... XXX */
BLI_freelistN(&sa1->regionbase);
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index da0cb0b73c1..414e3569c03 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -458,8 +458,6 @@ static void screen_copy(bScreen *to, bScreen *from)
sa->v4= sa->v4->newv;
sa->spacedata.first= sa->spacedata.last= NULL;
- sa->uiblocks.first= sa->uiblocks.last= NULL;
- sa->panels.first= sa->panels.last= NULL;
sa->regionbase.first= sa->regionbase.last= NULL;
sa->actionzones.first= sa->actionzones.last= NULL;
sa->scriptlink.totscript= 0;
diff --git a/source/blender/editors/space_action/action_draw.c b/source/blender/editors/space_action/action_draw.c
index 0b63cad4712..38f2fe39a8f 100644
--- a/source/blender/editors/space_action/action_draw.c
+++ b/source/blender/editors/space_action/action_draw.c
@@ -182,7 +182,7 @@ static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
if (i >= 255) break;
}
}
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
static void icu_slider_func(void *voidicu, void *voidignore)
@@ -387,7 +387,7 @@ static void action_icu_buts(SpaceAction *saction)
/* free tempolary channels */
BLI_freelistN(&act_data);
}
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
#endif // XXX all of this slider stuff will need a rethink
diff --git a/source/blender/editors/space_action/action_header.c b/source/blender/editors/space_action/action_header.c
index 635a40037b3..3a16454fb46 100644
--- a/source/blender/editors/space_action/action_header.c
+++ b/source/blender/editors/space_action/action_header.c
@@ -477,7 +477,7 @@ void action_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_buttons/Makefile b/source/blender/editors/space_buttons/Makefile
index 33fe2cfc9cb..ff82f25ea55 100644
--- a/source/blender/editors/space_buttons/Makefile
+++ b/source/blender/editors/space_buttons/Makefile
@@ -47,6 +47,7 @@ CPPFLAGS += -I../../makesdna
CPPFLAGS += -I../../imbuf
CPPFLAGS += -I../../python
CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include
+CPPFLAGS += -I../../render/extern/include
# own include
diff --git a/source/blender/editors/space_buttons/SConscript b/source/blender/editors/space_buttons/SConscript
index 50b76074be6..0bd5374c3ca 100644
--- a/source/blender/editors/space_buttons/SConscript
+++ b/source/blender/editors/space_buttons/SConscript
@@ -5,5 +5,6 @@ sources = env.Glob('*.c')
incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf'
incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include'
+incs += ' ../../render/extern/include'
env.BlenderLib ( 'bf_editors_space_buttons', sources, Split(incs), [], libtype=['core'], priority=[120] )
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 8121a4ac730..552093b47a5 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -101,6 +101,9 @@ static void do_buttons_buttons(bContext *C, void *arg, int event)
case B_NEWFRAME:
WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
break;
+ case B_CONTEXT_SWITCH:
+ ED_area_tag_redraw(CTX_wm_area(C));
+ break;
}
}
@@ -195,7 +198,7 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index 7c818488265..ffc325e59ab 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -72,10 +72,9 @@
/* internal exports only */
-
/* image_header.c */
void buttons_header_buttons(const bContext *C, ARegion *ar);
-
+void buttons_scene(const bContext *C, ARegion *ar);
#endif /* ED_BUTTONS_INTERN_H */
diff --git a/source/blender/editors/space_buttons/buttons_scene.c b/source/blender/editors/space_buttons/buttons_scene.c
new file mode 100644
index 00000000000..c5b03195017
--- /dev/null
+++ b/source/blender/editors/space_buttons/buttons_scene.c
@@ -0,0 +1,324 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2008 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+
+#include "BLI_threads.h"
+
+#include "BKE_context.h"
+#include "BKE_global.h"
+
+#include "RE_pipeline.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+
+#include "buttons_intern.h"
+
+#define R_DISPLAYIMAGE 0
+#define R_DISPLAYWIN 1
+#define R_DISPLAYSCREEN 2
+
+static void render_panel_output(const bContext *C, ARegion *ar)
+{
+ //ID *id;
+ int a,b;
+ uiBlock *block;
+ //char *strp;
+
+ block= uiBeginBlock(C, ar, "render_panel_output", UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, "Output", "Render", 0, 0, 318, 204)==0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefIconBut(block, BUT, 0, ICON_FILESEL, 10, 190, 20, 20, 0, 0, 0, 0, 0, "Select the directory/name for saving animations");
+ uiDefBut(block, TEX,0,"", 31, 190, 279, 20,G.scene->r.pic, 0.0,79.0, 0, 0, "Directory/name to save animations, # characters defines the position and length of frame numbers");
+ uiDefIconBut(block, BUT,0, ICON_FILESEL, 10, 168, 20, 20, 0, 0, 0, 0, 0, "Select the directory/name for a Backbuf image");
+ uiDefBut(block, TEX,0,"", 31, 168, 259, 20,G.scene->r.backbuf, 0.0,79.0, 0, 0, "Image to use as background for rendering");
+ uiDefIconButBitS(block, ICONTOG, R_BACKBUF, 0, ICON_CHECKBOX_HLT-1, 290, 168, 20, 20, &G.scene->r.bufflag, 0.0, 0.0, 0, 0, "Enable/Disable use of Backbuf image");
+ uiBlockEndAlign(block);
+
+ uiDefButBitI(block, TOG, R_EXTENSION, 0, "Extensions", 10, 142, 100, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Adds filetype extensions to the filename when rendering animations");
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_TOUCH, 0, "Touch", 170, 142, 50, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Create an empty file before rendering each frame, remove if cancelled (and empty)");
+ uiDefButBitI(block, TOG, R_NO_OVERWRITE, 0, "No Overwrite", 220, 142, 90, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Skip rendering frames when the file exists (image output only)");
+ uiBlockEndAlign(block);
+
+ /* SET BUTTON */
+ uiBlockBeginAlign(block);
+ /*XXX id= (ID *)G.scene->set;
+ IDnames_to_pupstring(&strp, NULL, NULL, &(G.main->scene), id, &(G.buts->menunr));
+ if(strp[0])
+ uiDefButS(block, MENU, 0, strp, 10, 114, 20, 20, &(G.buts->menunr), 0, 0, 0, 0, "Scene to link as a Set");
+ MEM_freeN(strp);*/
+
+ if(G.scene->set) {
+ uiBlockSetButLock(block, 1, NULL);
+ //XXX uiDefIDPoinBut(block, test_scenepoin_but, ID_SCE, 0, "", 31, 114, 100, 20, &(G.scene->set), "Name of the Set");
+ uiBlockClearButLock(block);
+ uiDefIconBut(block, BUT, 0, ICON_X, 132, 114, 20, 20, 0, 0, 0, 0, 0, "Remove Set link");
+ } else {
+ uiDefBut(block, LABEL, 0, "No Set Scene", 31, 114, 200, 20, 0, 0, 0, 0, 0, "");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefIconButBitI(block, TOGN, R_FIXED_THREADS, 0, ICON_AUTO, 10, 63, 20, 20, &G.scene->r.mode, 0.0, 0.0, 0, 0, "Automatically set the threads to the number of processors on the system");
+ if ((G.scene->r.mode & R_FIXED_THREADS)==0) {
+ char thread_str[16];
+ sprintf(thread_str, " Threads: %d", BLI_system_thread_count());
+ uiDefBut(block, LABEL, 0, thread_str, 30, 63,80,20, 0, 0, 0, 0, 0, "");
+ } else {
+ uiDefButS(block, NUM, 0, "Threads:", 30, 63, 80, 20, &G.scene->r.threads, 1, BLENDER_MAX_THREADS, 0, 0, "Amount of threads for render (takes advantage of multi-core and multi-processor computers)");
+ }
+ uiBlockEndAlign(block);
+
+ uiBlockSetCol(block, TH_AUTO);
+
+ uiBlockBeginAlign(block);
+ for(b=2; b>=0; b--)
+ for(a=0; a<3; a++)
+ uiDefButBitS(block, TOG, 1<<(3*b+a), 800,"", (short)(10+18*a),(short)(10+14*b),16,12, &G.winpos, 0, 0, 0, 0, "Render window placement on screen");
+ uiBlockEndAlign(block);
+
+#ifdef WITH_OPENEXR
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_EXR_TILE_FILE, 0, "Save Buffers", 72, 31, 120, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Save tiles for all RenderLayers and used SceneNodes to files in the temp directory (saves memory, allows Full Sampling)");
+ if(G.scene->r.scemode & R_EXR_TILE_FILE)
+ uiDefButBitI(block, TOG, R_FULL_SAMPLE, 0, "FullSample", 192, 31, 118, 19, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Saves for every OSA sample the entire RenderLayer results (Higher quality sampling but slower)");
+ uiBlockEndAlign(block);
+#endif
+
+ uiDefButS(block, MENU, 0, "Render Display %t|Render Window %x1|Image Editor %x0|Full Screen %x2",
+ 72, 10, 120, 19, &G.displaymode, 0.0, (float)R_DISPLAYWIN, 0, 0, "Sets render output display");
+
+ /* Dither control */
+ uiDefButF(block, NUM,0, "Dither:", 10,89,100,19, &G.scene->r.dither_intensity, 0.0, 2.0, 0, 0, "The amount of dithering noise present in the output image (0.0 = no dithering)");
+
+ /* Toon shading buttons */
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_EDGE, 0,"Edge", 115, 89, 60, 20, &G.scene->r.mode, 0, 0, 0, 0, "Enable Toon Edge-enhance");
+ //XXX uiDefBlockBut(block, edge_render_menu, NULL, "Edge Settings", 175, 89, 135, 20, "Display Edge settings");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_NO_TEX, 0, "Disable Tex", 115, 63, 75, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Disables Textures for render");
+ uiDefButBitI(block, TOG, R_FREE_IMAGE, 0, "Free Tex Images", 210, 63, 100, 20, &G.scene->r.scemode, 0.0, 0.0, 0, 0, "Frees all Images used by Textures after each render");
+ uiBlockEndAlign(block);
+
+ uiEndBlock(C, block);
+}
+
+static void do_bake_func(bContext *C, void *unused_v, void *unused_p)
+{
+ //XXX objects_bake_render_ui(0);
+}
+
+static void render_panel_bake(const bContext *C, ARegion *ar)
+{
+ uiBlock *block;
+ uiBut *but;
+
+ block= uiBeginBlock(C, ar, "render_panel_bake", UI_EMBOSS, UI_HELV);
+ uiNewPanelTabbed("Anim", "Render");
+ if(uiNewPanel(C, ar, block, "Bake", "Render", 320, 0, 318, 204)==0) return;
+
+ but= uiDefBut(block, BUT, 0, "BAKE", 10, 150, 190,40, 0, 0, 0, 0, 0, "Start the bake render for selected Objects");
+ uiButSetFunc(but, do_bake_func, NULL, NULL);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, R_BAKE_TO_ACTIVE, 0, "Selected to Active", 10,120,190,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Bake shading on the surface of selected objects to the active object");
+ uiDefButF(block, NUM, 0, "Dist:", 10,100,95,20,&G.scene->r.bake_maxdist, 0.0, 1000.0, 1, 0, "Maximum distance from active object to other object (in blender units)");
+ uiDefButF(block, NUM, 0, "Bias:", 105,100,95,20,&G.scene->r.bake_biasdist, 0.0, 1000.0, 1, 0, "Bias towards faces further away from the object (in blender units)");
+ uiBlockEndAlign(block);
+
+ if(G.scene->r.bake_mode == RE_BAKE_NORMALS)
+ uiDefButS(block, MENU, 0, "Normal Space %t|Camera %x0|World %x1|Object %x2|Tangent %x3",
+ 10,70,190,20, &G.scene->r.bake_normal_space, 0, 0, 0, 0, "Choose normal space for baking");
+ else if(G.scene->r.bake_mode == RE_BAKE_AO || G.scene->r.bake_mode == RE_BAKE_DISPLACEMENT) {
+ uiDefButBitS(block, TOG, R_BAKE_NORMALIZE, 0, "Normalized", 10,70,190,20, &G.scene->r.bake_flag, 0.0, 0, 0, 0,
+ G.scene->r.bake_mode == RE_BAKE_AO ?
+ "Bake ambient occlusion normalized, without taking into acount material settings":
+ "Normalized displacement value to fit the 'Dist' range"
+ );
+ }
+
+ uiDefButS(block, MENU, 0, "Quad Split Order%t|Quad Split Auto%x0|Quad Split A (0,1,2) (0,2,3)%x1|Quad Split B (1,2,3) (1,3,0)%x2",
+ 10,10,190,20, &G.scene->r.bake_quad_split, 0, 0, 0, 0, "Method to divide quads (use A or B for external applications that use a fixed order)");
+
+#if 0
+ uiBlockBeginAlign(block);
+ uiDefButBitS(block, TOG, R_BAKE_OSA, 0, "OSA", 10,120,190,20, &G.scene->r.bake_flag, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
+ uiDefButS(block, ROW,0,"5", 10,100,50,20,&G.scene->r.bake_osa,2.0,5.0, 0, 0, "Sets oversample level to 5");
+ uiDefButS(block, ROW,0,"8", 60,100,45,20,&G.scene->r.bake_osa,2.0,8.0, 0, 0, "Sets oversample level to 8");
+ uiDefButS(block, ROW,0,"11", 105,100,45,20,&G.scene->r.bake_osa,2.0,11.0, 0, 0, "Sets oversample level to 11");
+ uiDefButS(block, ROW,0,"16", 150,100,50,20,&G.scene->r.bake_osa,2.0,16.0, 0, 0, "Sets oversample level to 16");
+#endif
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW,0,"Full Render", 210,170,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_ALL, 0, 0, "");
+ uiDefButS(block, ROW,0,"Ambient Occlusion",210,150,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_AO, 0, 0, "");
+ uiDefButS(block, ROW,0,"Shadow", 210,130,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_SHADOW, 0, 0, "");
+ uiDefButS(block, ROW,0,"Normals", 210,110,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_NORMALS, 0, 0, "");
+ uiDefButS(block, ROW,0,"Textures", 210,90,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_TEXTURE, 0, 0, "");
+ uiDefButS(block, ROW,0,"Displacement", 210,70,120,20,&G.scene->r.bake_mode, 1.0, RE_BAKE_DISPLACEMENT, 0, 0, "");
+ uiBlockEndAlign(block);
+
+ uiDefButBitS(block, TOG, R_BAKE_CLEAR, 0, "Clear", 210,40,120,20,&G.scene->r.bake_flag, 0.0, 0, 0, 0, "Clear Images before baking");
+
+ uiDefButS(block, NUM, 0,"Margin:", 210,10,120,20,&G.scene->r.bake_filter, 0.0, 32.0, 0, 0, "Amount of pixels to extend the baked result with, as post process filter");
+
+ uiEndBlock(C, block);
+}
+
+static void render_panel_render(const bContext *C, ARegion *ar)
+{
+ uiBlock *block;
+ char str[256];
+
+ block= uiBeginBlock(C, ar, "render_panel_render", UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, "Render", "Render", 320, 0, 318, 204)==0) return;
+
+ uiBlockBeginAlign(block);
+ uiDefBut(block, BUT,0,"RENDER", 369, 164, 191,37, 0, 0, 0, 0, 0, "Render the current frame (F12)");
+#ifndef DISABLE_YAFRAY
+ /* yafray: on request, render engine menu is back again, and moved to Render panel */
+ uiDefButS(block, MENU, 0, "Rendering Engine %t|Blender Internal %x0|YafRay %x1",
+ 369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");
+#else
+ uiDefButS(block, MENU, 0, "Rendering Engine %t|Blender Internal %x0",
+ 369, 142, 191, 20, &G.scene->r.renderer, 0, 0, 0, 0, "Choose rendering engine");
+#endif /* disable yafray */
+
+ uiBlockBeginAlign(block);
+ if((G.scene->r.scemode & R_FULL_SAMPLE) && (G.scene->r.scemode & R_EXR_TILE_FILE))
+ uiDefButBitI(block, TOG, R_OSA, 0, "FSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Saves all samples, then composites, and then merges (for best Anti-aliasing)");
+ else
+ uiDefButBitI(block, TOG, R_OSA, 0, "OSA", 369,109,122,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Oversampling (Anti-aliasing)");
+ uiDefButS(block, ROW,0,"5", 369,88,29,20,&G.scene->r.osa,2.0,5.0, 0, 0, "Render 5 samples per pixel for smooth edges (Fast)");
+ uiDefButS(block, ROW,0,"8", 400,88,29,20,&G.scene->r.osa,2.0,8.0, 0, 0, "Render 8 samples per pixel for smooth edges (Recommended)");
+ uiDefButS(block, ROW,0,"11", 431,88,29,20,&G.scene->r.osa,2.0,11.0, 0, 0, "Render 11 samples per pixel for smooth edges (High Quality)");
+ uiDefButS(block, ROW,0,"16", 462,88,29,20,&G.scene->r.osa,2.0,16.0, 0, 0, "Render 16 samples per pixel for smooth edges (Highest Quality)");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_MBLUR, 0, "MBLUR", 496,109,64,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Motion Blur calculation");
+ uiDefButF(block, NUM,0,"Bf:", 496,88,64,20,&G.scene->r.blurfac, 0.01, 5.0, 10, 2, "Sets motion blur factor");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, NUM,0,"Xparts:", 369,46,95,29,&G.scene->r.xparts,1.0, 512.0, 0, 0, "Sets the number of horizontal parts to render image in (For panorama sets number of camera slices)");
+ uiDefButS(block, NUM,0,"Yparts:", 465,46,95,29,&G.scene->r.yparts,1.0, 64.0, 0, 0, "Sets the number of vertical parts to render image in");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW,800,"Sky", 369,13,35,20,&G.scene->r.alphamode,3.0,0.0, 0, 0, "Fill background with sky");
+ uiDefButS(block, ROW,800,"Premul", 405,13,50,20,&G.scene->r.alphamode,3.0,1.0, 0, 0, "Multiply alpha in advance");
+ uiDefButS(block, ROW,800,"Key", 456,13,35,20,&G.scene->r.alphamode,3.0,2.0, 0, 0, "Alpha and color values remain unchanged");
+ uiBlockEndAlign(block);
+
+ uiDefButS(block, MENU, 0,"Octree resolution %t|64 %x64|128 %x128|256 %x256|512 %x512", 496,13,64,20,&G.scene->r.ocres,0.0,0.0, 0, 0, "Octree resolution for ray tracing and baking, Use higher values for complex scenes");
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_SHADOW, 0,"Shadow", 565,172,52,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable shadow calculation");
+ uiDefButBitI(block, TOG, R_SSS, 0,"SSS", 617,172,32,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable subsurface scattering map rendering");
+ uiDefButBitI(block, TOG, R_PANORAMA, 0,"Pano", 649,172,38,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable panorama rendering (output width is multiplied by Xparts)");
+ uiDefButBitI(block, TOG, R_ENVMAP, 0,"EnvMap", 565,142,52,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable environment map rendering");
+ uiDefButBitI(block, TOG, R_RAYTRACE, 0,"Ray",617,142,32,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable ray tracing");
+ uiDefButBitI(block, TOG, R_RADIO, 0,"Radio", 649,142,38,29, &G.scene->r.mode, 0, 0, 0, 0, "Enable radiosity rendering");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButS(block, ROW,0,"100%", 565,109,122,20,&G.scene->r.size,1.0,100.0, 0, 0, "Set render size to defined size");
+ uiDefButS(block, ROW,0,"75%", 565,88,40,20,&G.scene->r.size,1.0,75.0, 0, 0, "Set render size to 3/4 of defined size");
+ uiDefButS(block, ROW,0,"50%", 606,88,40,20,&G.scene->r.size,1.0,50.0, 0, 0, "Set render size to 1/2 of defined size");
+ uiDefButS(block, ROW,0,"25%", 647,88,40,20,&G.scene->r.size,1.0,25.0, 0, 0, "Set render size to 1/4 of defined size");
+ uiBlockEndAlign(block);
+
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_FIELDS, 0,"Fields", 565,55,60,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables field rendering");
+ uiDefButBitI(block, TOG, R_ODDFIELD, 0,"Odd", 627,55,39,20,&G.scene->r.mode, 0, 0, 0, 0, "Enables Odd field first rendering (Default: Even field)");
+ uiDefButBitI(block, TOG, R_FIELDSTILL, 0,"X", 668,55,19,20,&G.scene->r.mode, 0, 0, 0, 0, "Disables time difference in field calculations");
+
+ sprintf(str, "Filter%%t|Box %%x%d|Tent %%x%d|Quad %%x%d|Cubic %%x%d|Gauss %%x%d|CatRom %%x%d|Mitch %%x%d", R_FILTER_BOX, R_FILTER_TENT, R_FILTER_QUAD, R_FILTER_CUBIC, R_FILTER_GAUSS, R_FILTER_CATROM, R_FILTER_MITCH);
+ uiDefButS(block, MENU, 0,str, 565,34,60,20, &G.scene->r.filtertype, 0, 0, 0, 0, "Set sampling filter for antialiasing");
+ uiDefButF(block, NUM,0,"", 627,34,60,20,&G.scene->r.gauss,0.5, 1.5, 10, 2, "Sets the filter size");
+
+ uiDefButBitI(block, TOG, R_BORDER, 0, "Border", 565,13,122,20, &G.scene->r.mode, 0, 0, 0, 0, "Render a small cut-out of the image (Shift+B to set in the camera view)");
+ uiBlockEndAlign(block);
+
+ uiEndBlock(C, block);
+}
+
+
+void render_panel_anim(const bContext *C, ARegion *ar)
+{
+ Scene *scene= CTX_data_scene(C);
+ uiBlock *block;
+
+ block= uiBeginBlock(C, ar, "render_panel_anim", UI_EMBOSS, UI_HELV);
+ if(uiNewPanel(C, ar, block, "Anim", "Render", 640, 0, 318, 204) == 0) return;
+
+ uiDefBut(block, BUT, 0, "ANIM", 692,142,192,47, 0, 0, 0, 0, 0, "Render the animation to disk from start to end frame, (Ctrl+F12)");
+
+ uiBlockSetCol(block, TH_BUT_SETTING1);
+ uiBlockBeginAlign(block);
+ uiDefButBitI(block, TOG, R_DOSEQ, 0, "Do Sequence",692,114,192,20, &scene->r.scemode, 0, 0, 0, 0, "Enables sequence output rendering (Default: 3D rendering)");
+ uiDefButBitI(block, TOG, R_DOCOMP, 0, "Do Composite",692,90,192,20, &scene->r.scemode, 0, 0, 0, 0, "Uses compositing nodes for output rendering");
+ uiBlockEndAlign(block);
+
+ uiBlockSetCol(block, TH_AUTO);
+ uiDefBut(block, BUT, 0, "PLAY",692,50,94,33, 0, 0, 0, 0, 0, "Play rendered images/avi animation (Ctrl+F11), (Play Hotkeys: A-Noskip, P-PingPong)");
+ uiDefButS(block, NUM, 0, "rt:",789,50,95,33, &G.rt, -1000.0, 1000.0, 0, 0, "General testing/debug button");
+
+ uiBlockBeginAlign(block);
+ uiDefButI(block, NUM,0,"Sta:",692,20,94,24, &scene->r.sfra,1.0,MAXFRAMEF, 0, 0, "The start frame of the animation (inclusive)");
+ uiDefButI(block, NUM,0,"End:",789,20,95,24, &scene->r.efra,SFRA,MAXFRAMEF, 0, 0, "The end frame of the animation (inclusive)");
+ uiDefButI(block, NUM,0,"Step:",692,0,192,18, &scene->frame_step, 1.0, MAXFRAMEF, 0, 0, "Frame Step");
+ uiBlockEndAlign(block);
+
+ uiEndBlock(C, block);
+}
+
+void buttons_scene(const bContext *C, ARegion *ar)
+{
+ SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
+ int tab= sbuts->tab[CONTEXT_SCENE];
+
+ if(tab == TAB_SCENE_RENDER) {
+ render_panel_output(C, ar);
+ render_panel_render(C, ar);
+ render_panel_anim(C, ar);
+ render_panel_bake(C, ar);
+ }
+}
+
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 088664f5343..d22e2943670 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -158,9 +158,10 @@ static void buttons_main_area_init(wmWindowManager *wm, ARegion *ar)
static void buttons_main_area_draw(const bContext *C, ARegion *ar)
{
/* draw entirely, view changes should be handled here */
- // SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
+ SpaceButs *sbuts= (SpaceButs*)CTX_wm_space_data(C);
View2D *v2d= &ar->v2d;
float col[3], fac;
+ int align= 0;
/* clear and setup matrix */
UI_GetThemeColor3fv(TH_BACK, col);
@@ -174,8 +175,16 @@ static void buttons_main_area_draw(const bContext *C, ARegion *ar)
glColor3f(fac, fac, fac);
glRecti(20, 2, 30, 12);
- /* data... */
+ /* panels */
+ if(sbuts->mainb == CONTEXT_SCENE)
+ buttons_scene(C, ar);
+ if(sbuts->align)
+ if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb])
+ align= 1;
+
+ uiDrawPanels(C, align);
+ uiMatchPanelsView2d(ar);
/* reset view matrix */
UI_view2d_view_restore(C);
@@ -247,7 +256,7 @@ void ED_spacetype_buttons(void)
art->init= buttons_main_area_init;
art->draw= buttons_main_area_draw;
art->listener= buttons_main_area_listener;
- art->keymapflag= ED_KEYMAP_VIEW2D;
+ art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D;
BLI_addhead(&st->regiontypes, art);
diff --git a/source/blender/editors/space_file/file_header.c b/source/blender/editors/space_file/file_header.c
index 296ccda156c..ccaa0acbfd3 100644
--- a/source/blender/editors/space_file/file_header.c
+++ b/source/blender/editors/space_file/file_header.c
@@ -128,7 +128,7 @@ void file_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_image/image_header.c b/source/blender/editors/space_image/image_header.c
index 51962a02779..6363718779a 100644
--- a/source/blender/editors/space_image/image_header.c
+++ b/source/blender/editors/space_image/image_header.c
@@ -127,7 +127,7 @@ void image_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_info/info_header.c b/source/blender/editors/space_info/info_header.c
index 04e78860995..4ee5939d1c5 100644
--- a/source/blender/editors/space_info/info_header.c
+++ b/source/blender/editors/space_info/info_header.c
@@ -150,7 +150,7 @@ void info_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_ipo/ipo_header.c b/source/blender/editors/space_ipo/ipo_header.c
index 1dd191e2fa7..da39fbacc44 100644
--- a/source/blender/editors/space_ipo/ipo_header.c
+++ b/source/blender/editors/space_ipo/ipo_header.c
@@ -126,7 +126,7 @@ void ipo_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_nla/nla_header.c b/source/blender/editors/space_nla/nla_header.c
index 6d30615d8b1..ef850df1c59 100644
--- a/source/blender/editors/space_nla/nla_header.c
+++ b/source/blender/editors/space_nla/nla_header.c
@@ -127,7 +127,7 @@ void nla_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index 2f09f87ef9e..3d45a42fc70 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -98,7 +98,7 @@
extern void ui_dropshadow(rctf *rct, float radius, float aspect, int select);
extern void ui_rasterpos_safe(float x, float y, float aspect);
extern void gl_round_box(int mode, float minx, float miny, float maxx, float maxy, float rad);
-void ui_draw_tria_icon(float x, float y, float aspect, char dir) {}
+extern void ui_draw_tria_icon(float x, float y, float aspect, char dir);
// XXX butspace.h
#define B_NODE_EXEC 3610
@@ -837,7 +837,7 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
if(node->typeinfo->butfunc) {
node->typeinfo->butfunc(block, snode->nodetree, node, &node->butr);
}
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
}
@@ -1155,4 +1155,4 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d)
scrollers= UI_view2d_scrollers_calc(C, v2d, 10/*unit*/, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
UI_view2d_scrollers_draw(C, v2d, scrollers);
UI_view2d_scrollers_free(scrollers);
-} \ No newline at end of file
+}
diff --git a/source/blender/editors/space_node/node_header.c b/source/blender/editors/space_node/node_header.c
index 7877aba4e7a..53e65194516 100644
--- a/source/blender/editors/space_node/node_header.c
+++ b/source/blender/editors/space_node/node_header.c
@@ -783,7 +783,7 @@ void node_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, (int)(ar->v2d.tot.ymax-ar->v2d.tot.ymin));
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c
index 8122ac0e3aa..cafe9acb96a 100644
--- a/source/blender/editors/space_outliner/outliner.c
+++ b/source/blender/editors/space_outliner/outliner.c
@@ -3828,7 +3828,7 @@ void draw_outliner(const bContext *C)
}
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
/* clear flag that allows quick redraws */
soops->storeflag &= ~SO_TREESTORE_REDRAW;
diff --git a/source/blender/editors/space_outliner/outliner_header.c b/source/blender/editors/space_outliner/outliner_header.c
index 4a4a6c80504..5f2d2809497 100644
--- a/source/blender/editors/space_outliner/outliner_header.c
+++ b/source/blender/editors/space_outliner/outliner_header.c
@@ -228,7 +228,7 @@ void outliner_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_outliner/space_outliner.c b/source/blender/editors/space_outliner/space_outliner.c
index ce6d99d7fa3..48c12c527c5 100644
--- a/source/blender/editors/space_outliner/space_outliner.c
+++ b/source/blender/editors/space_outliner/space_outliner.c
@@ -144,7 +144,7 @@ void UI_table_draw(const bContext *C, uiTable *table)
fdrawline(rct->xmin+COLUMN_WIDTH*(col+1), rct->ymin, rct->xmin+COLUMN_WIDTH*(col+1), rct->ymax);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_script/script_header.c b/source/blender/editors/space_script/script_header.c
index 9eb9d2f3f94..37e77e1497a 100644
--- a/source/blender/editors/space_script/script_header.c
+++ b/source/blender/editors/space_script/script_header.c
@@ -127,7 +127,7 @@ void script_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_sequencer/sequencer_header.c b/source/blender/editors/space_sequencer/sequencer_header.c
index 34e73c23381..df6c3491480 100644
--- a/source/blender/editors/space_sequencer/sequencer_header.c
+++ b/source/blender/editors/space_sequencer/sequencer_header.c
@@ -127,7 +127,7 @@ void sequencer_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_sound/sound_header.c b/source/blender/editors/space_sound/sound_header.c
index 264735b2215..7e47cb832a2 100644
--- a/source/blender/editors/space_sound/sound_header.c
+++ b/source/blender/editors/space_sound/sound_header.c
@@ -127,7 +127,7 @@ void sound_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_text/text_header.c b/source/blender/editors/space_text/text_header.c
index e347b85d709..84182f70cdb 100644
--- a/source/blender/editors/space_text/text_header.c
+++ b/source/blender/editors/space_text/text_header.c
@@ -127,7 +127,7 @@ void text_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_time/time_header.c b/source/blender/editors/space_time/time_header.c
index 04f01803c1c..a4e26400417 100644
--- a/source/blender/editors/space_time/time_header.c
+++ b/source/blender/editors/space_time/time_header.c
@@ -553,7 +553,7 @@ void time_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index 35c686bc54e..dac80f09646 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -5995,7 +5995,7 @@ void view3d_header_buttons(const bContext *C, ARegion *ar)
UI_view2d_totRect_set(&ar->v2d, xco+XIC+80, ar->v2d.tot.ymax-ar->v2d.tot.ymin);
uiEndBlock(C, block);
- uiDrawBlock(block);
+ uiDrawBlock(C, block);
}
diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h
index af8597ba54d..9de835da9f1 100644
--- a/source/blender/makesdna/DNA_screen_types.h
+++ b/source/blender/makesdna/DNA_screen_types.h
@@ -36,6 +36,7 @@
struct SpaceType;
struct SpaceLink;
+struct ARegion;
struct ARegionType;
struct Scene;
struct wmTimer;
@@ -88,9 +89,9 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
short flag, active; /* active= used currently by a uiBlock */
short control;
short snap;
- short old_ofsx, old_ofsy; /* for stow */
- int sortcounter; /* when sorting panels, it uses this to put new ones in right place */
+ int sortcounter, pad; /* when sorting panels, it uses this to put new ones in right place */
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
+ void *activedata; /* runtime for panel manipulation */
} Panel;
typedef struct ScrArea {
@@ -112,9 +113,7 @@ typedef struct ScrArea {
struct SpaceType *type; /* callbacks for this space type */
- ListBase spacedata;
- ListBase uiblocks; /* uiBlock */
- ListBase panels;
+ ListBase spacedata; /* SpaceLink */
ListBase regionbase; /* ARegion */
ListBase handlers; /* wmEventHandler */
@@ -141,7 +140,8 @@ typedef struct ARegion {
struct ARegionType *type; /* callbacks for this region type */
- ListBase uiblocks;
+ ListBase uiblocks; /* uiBlock */
+ ListBase panels; /* Panel */
ListBase handlers; /* wmEventHandler */
char *headerstr; /* use this string to draw info */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 0bd99a9adfa..1aec7856da4 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -436,10 +436,9 @@ typedef struct SpaceImaSel {
/* **************** SPACE DEFINES ********************* */
-
/* button defines */
/* warning: the values of these defines are used in sbuts->tabs[7] */
-/* buts->mainb new */
+/* sbuts->mainb new */
#define CONTEXT_SCENE 0
#define CONTEXT_OBJECT 1
#define CONTEXT_TYPES 2
@@ -448,7 +447,7 @@ typedef struct SpaceImaSel {
#define CONTEXT_SCRIPT 5
#define CONTEXT_LOGIC 6
-/* buts->tab new */
+/* sbuts->tab new */
#define TAB_SHADING_MAT 0
#define TAB_SHADING_TEX 1
#define TAB_SHADING_RAD 2
@@ -465,10 +464,13 @@ typedef struct SpaceImaSel {
#define TAB_SCENE_SOUND 3
#define TAB_SCENE_SEQUENCER 4
-
/* sbuts->flag */
#define SB_PRV_OSA 1
+/* sbuts->align */
+#define BUT_HORIZONTAL 1
+#define BUT_VERTICAL 2
+
/* these values need to be hardcoded in structs, dna does not recognize defines */
/* also defined in BKE */
#define FILE_MAXDIR 160