diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-17 01:39:45 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-04-17 01:39:45 +0400 |
commit | 38b6f8f167662db35e8b51e8d9b2ecb13800982a (patch) | |
tree | 6500a4395e401d9a2fd82f5bdfd37ceeaa7072e4 | |
parent | a565154a8749df90c18df251049b0f8e613c3825 (diff) |
UI:
* For new buttons spaces, automatically set horizontal/vertical
align depending on size, instead of free.
* Cleaned up the UI panel API. There's now a new uiBeginPanel
function which takes a panel type, and a uiEndPanel which takes
the final size. uiNewPanel* functions will be phased out.
* Animate the re-alignment when a panel size changes, e.g. when
enabling dupliframes.
* Load ui scripts from the release/ folder first if it is
available. This makes it easier to edit ui scripts, since it
will directly use the original files which avoids having to
run the build system.
* Improve editing of panel types while blender is open. That
means fixing some issues with lacking updates, overlaps, strange
ordering. It even does an animation now when the panel resizes.
-rw-r--r-- | source/blender/blenlib/intern/util.c | 35 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/include/UI_interface.h | 16 | ||||
-rw-r--r-- | source/blender/editors/interface/interface.c | 3 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_layout.c | 26 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_panel.c | 467 | ||||
-rw-r--r-- | source/blender/editors/interface/interface_utils.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_buttons/space_buttons.c | 19 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_screen_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_space_types.h | 2 | ||||
-rw-r--r-- | source/blender/python/intern/bpy_panel_wrap.c | 32 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 2 |
13 files changed, 356 insertions, 256 deletions
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 88f5038e19f..3d55a048d5f 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -831,10 +831,10 @@ char *BLI_gethome(void) { /* this function returns the path to a blender folder, if it exists, * trying in this order: * - * $HOME/.blender/folder_name - * path_to_executable/.blender/folder_name * path_to_executable/release/folder_name (in svn) * ./release/folder_name (in svn) + * $HOME/.blender/folder_name + * path_to_executable/.blender/folder_name * * returns NULL if none is found. */ @@ -848,12 +848,20 @@ char *BLI_gethome_folder(char *folder_name) char *s; int i; + /* try path_to_executable/release/folder_name (in svn) */ + if (folder_name) { + BLI_snprintf(tmpdir, sizeof(tmpdir), "release/%s", folder_name); + BLI_make_file_string("/", fulldir, bprogdir, tmpdir); + if (BLI_exists(fulldir)) return fulldir; + else fulldir[0] = '\0'; + } + + /* try ./release/folder_name (in svn) */ if(folder_name) { - if(fulldir[0] != '\0') - return fulldir; + BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name); + if (BLI_exists(fulldir)) return fulldir; + else fulldir[0] = '\0'; } - else if(homedir[0] != '\0') - return homedir; /* BLI_gethome() can return NULL if env vars are not set */ s = BLI_gethome(); @@ -913,21 +921,6 @@ char *BLI_gethome_folder(char *folder_name) else return homedir; } - /* try path_to_executable/release/folder_name (in svn) */ - if (folder_name) { - BLI_snprintf(tmpdir, sizeof(tmpdir), "release/%s", folder_name); - BLI_make_file_string("/", fulldir, bprogdir, tmpdir); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } - - /* try ./release/folder_name (in svn) */ - if(folder_name) { - BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } - return NULL; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 8ea1c4a08f4..8e9194b6122 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4460,7 +4460,7 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype) for(pa= ar->panels.first; pa; pa=pa->next) { pa->paneltab= newdataadr(fd, pa->paneltab); - pa->active= 0; + pa->runtime_flag= 0; pa->sortcounter= 0; pa->activedata= NULL; pa->type= NULL; diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index f3da97a801e..5a827a2311b 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -481,18 +481,18 @@ void autocomplete_end(AutoComplete *autocpl, char *autoname); * could use a good cleanup, though how they will function in 2.5 is * not clear yet so we postpone that. */ -extern void uiNewPanelTabbed(char *, char *); -extern int uiNewPanel(const struct bContext *C, struct ARegion *ar, uiBlock *block, char *panelname, char *tabname, int ofsx, int ofsy, int sizex, int sizey); +void uiBeginPanels(const struct bContext *C, struct ARegion *ar); +void uiEndPanels(const struct bContext *C, struct ARegion *ar); + +struct Panel *uiBeginPanel(struct ARegion *ar, uiBlock *block, struct PanelType *pt); +void uiEndPanel(uiBlock *block, int width, int height); -extern void uiBeginPanels(const struct bContext *C, struct ARegion *ar); -extern void uiEndPanels(const struct bContext *C, struct ARegion *ar); -extern void uiFreePanels(struct ListBase *lb); - -extern void uiPanelsHome(struct ARegion *ar); +void uiPanelsHome(struct ARegion *ar); +/* deprecated */ +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 uiNewPanelHeight(struct uiBlock *block, int sizey); extern void uiNewPanelTitle(struct uiBlock *block, char *str); -struct Panel *uiPanelFromBlock(struct uiBlock *block); /* Handlers * diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index dd3b75ad0d7..47c73c3398d 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1688,9 +1688,6 @@ void uiFreeBlock(const bContext *C, uiBlock *block) ui_free_but(C, but); } - if(block->panel) { - block->panel->active= 0; - } BLI_freelistN(&block->saferct); MEM_freeN(block); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b3216412b68..ff2bccff1ac 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -1216,26 +1216,26 @@ void uiRegionPanelLayout(const bContext *C, ARegion *ar, int vertical, char *con if(pt->draw && (!pt->poll || pt->poll(C))) { block= uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - - if(vertical) { - w= (ar->type->minsizex)? ar->type->minsizex-12: block->aspect*ar->winx-12; - em= (ar->type->minsizex)? 10: 20; - } - else { - w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12; - em= (ar->type->minsizex)? 10: 20; - } + panel= uiBeginPanel(ar, block, pt); + + if(panel) { + if(vertical) { + w= (ar->type->minsizex)? ar->type->minsizex-12: block->aspect*ar->winx-12; + em= (ar->type->minsizex)? 10: 20; + } + else { + w= (ar->type->minsizex)? ar->type->minsizex-12: UI_PANEL_WIDTH-12; + em= (ar->type->minsizex)? 10: 20; + } - if(uiNewPanel(C, ar, block, pt->name, pt->name, x, y, w, 0)) { - panel= uiPanelFromBlock(block); panel->type= pt; - panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, w, em); + panel->layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, PNL_SAFETY, 0, w-2*PNL_SAFETY, em); pt->draw(C, panel); uiLayoutEnd(C, block, panel->layout, &xco, &yco); panel->layout= NULL; - uiNewPanelHeight(block, y - yco + 12); + uiEndPanel(block, w, -yco + 12); } else { w= PNL_HEADER; diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 9e7d13b68cc..807fc552de4 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -25,10 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/* - a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt - - */ +/* a full doc with API notes can be found in bf-blender/blender/doc/interface_API.txt */ #include <math.h> #include <stdlib.h> @@ -63,11 +60,16 @@ #include "interface_intern.h" -/* Defines */ +/*********************** defines and structs ************************/ #define ANIMATION_TIME 0.30 #define ANIMATION_INTERVAL 0.02 +#define PNL_LAST_ADDED 1 +#define PNL_ACTIVE 2 +#define PNL_WAS_ACTIVE 4 +#define PNL_ANIM_ALIGN 8 + typedef enum uiHandlePanelState { PANEL_STATE_DRAG, PANEL_STATE_DRAG_SCALE, @@ -89,11 +91,10 @@ typedef struct uiHandlePanelData { int startsizex, startsizey; } uiHandlePanelData; -static void panel_activate_state(bContext *C, Panel *pa, uiHandlePanelState state); +static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state); -/* ******************************** */ - -/* temporary code to remove all sbuts stuff from panel code */ +/*********************** space specific code ************************/ +/* temporary code to remove all sbuts stuff from panel code */ static int panel_aligned(ScrArea *sa, ARegion *ar) { @@ -107,26 +108,46 @@ static int panel_aligned(ScrArea *sa, ARegion *ar) return 0; } -static int panels_re_align(ScrArea *sa, ARegion *ar) +static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa) { + Panel *pa; + int active= 0; + + *r_pa= NULL; + if(sa->spacetype==SPACE_BUTS && ar->regiontype == RGN_TYPE_WINDOW) { SpaceButs *sbuts= sa->spacedata.first; if(sbuts->align) if(sbuts->re_align || sbuts->mainbo!=sbuts->mainb || sbuts->tabo!=sbuts->tab[sbuts->mainb]) return 1; - - return 0; } else if(ar->regiontype==RGN_TYPE_UI) return 1; + + for(pa=ar->panels.first; pa; pa=pa->next) { + if((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) + return 1; + if(!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE)) + return 1; + if(pa->activedata) + active= 1; + } + + for(pa=ar->panels.first; pa; pa=pa->next) { + if(pa->runtime_flag & PNL_ANIM_ALIGN) { + if(!active) + *r_pa= pa; + return 1; + } + } return 0; } -/* ************** panels ************* */ +/****************************** panels ******************************/ -static void copy_panel_offset(Panel *pa, Panel *papar) +static void ui_panel_copy_offset(Panel *pa, Panel *papar) { /* with respect to sizes... papar is parent */ @@ -134,30 +155,118 @@ static void copy_panel_offset(Panel *pa, Panel *papar) 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 *uiBeginPanel(ARegion *ar, uiBlock *block, PanelType *pt) { - panel_tabbed= panelname; - group_tabbed= groupname; -} + Panel *pa, *patab, *palast; + char *panelname= pt->name; + char *tabname= pt->name; + char *hookname= NULL; + + /* 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) { + pa->type= pt; + BLI_remlink(&ar->panels, pa); + } + else { + /* new panel */ + pa= MEM_callocN(sizeof(Panel), "new panel"); + pa->type= pt; + BLI_strncpy(pa->panelname, panelname, UI_MAX_NAME_STR); + BLI_strncpy(pa->tabname, tabname, UI_MAX_NAME_STR); + + pa->ofsx= PNL_DIST; + pa->ofsy= PNL_DIST; + pa->sizex= 0; + pa->sizey= 0; + + /* make new Panel tabbed? */ + if(hookname) { + for(patab= ar->panels.first; patab; patab= patab->next) { + if((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab==NULL) { + if(strncmp(hookname, patab->panelname, UI_MAX_NAME_STR)==0) { + if(strncmp(tabname, patab->tabname, UI_MAX_NAME_STR)==0) { + pa->paneltab= patab; + ui_panel_copy_offset(pa, patab); + break; + } + } + } + } + } + } -/* another global... */ -static int pnl_control= UI_PNL_TRANSP; + /* insert panel into list and set sort counter */ + pa->runtime_flag |= PNL_LAST_ADDED; -void uiPanelControl(int control) -{ - pnl_control= control; + for(palast=ar->panels.first; palast; palast=palast->next) + if(palast->runtime_flag & PNL_LAST_ADDED) + break; + + if(palast) { + palast->runtime_flag &= ~PNL_LAST_ADDED; + pa->sortcounter= palast->sortcounter+1; + BLI_insertlink(&ar->panels, palast, pa); + } + else { + pa->sortcounter= 0; + BLI_addtail(&ar->panels, pa); + } + + /* assign to block */ + block->panel= pa; + pa->runtime_flag |= PNL_ACTIVE; + + if(pa->paneltab) return NULL; + if(pa->flag & PNL_CLOSED) return NULL; + + /* the 'return 0' above makes this to be in end. otherwise closes panels show wrong title */ + pa->drawname[0]= 0; + + return pa; } -/* another global... */ -static int pnl_handler= 0; +void uiEndPanel(uiBlock *block, int width, int height) +{ + Panel *pa= block->panel; + + if(pa->sizex != width || pa->sizey != height) { + pa->runtime_flag |= PNL_ANIM_ALIGN; + pa->ofsy += pa->sizey-height; + } + + pa->sizex= width; + pa->sizey= height; +} -void uiSetPanelHandler(int handler) +#if 0 +void uiPanelToMouse(const bContext *C, Panel *pa) { - pnl_handler= handler; + /* global control over this feature; UI_PNL_TO_MOUSE only called for hotkey panels */ + if(U.uiflag & USER_PANELPINNED); + else if(pa->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(pa->control & UI_PNL_UNSTOW) { + if(pa->flag & PNL_CLOSEDY) { + pa->flag &= ~PNL_CLOSED; + } + } } +#endif /* ofsx/ofsy only used for new panel definitions */ /* return 1 if visible (create buttons!) */ @@ -194,6 +303,7 @@ int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname, pa->sizex= sizex; pa->sizey= sizey; +#if 0 /* make new Panel tabbed? */ if(panel_tabbed && group_tabbed) { Panel *papar; @@ -209,36 +319,16 @@ int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname, } } } +#endif } block->panel= pa; - 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; + pa->runtime_flag |= PNL_ACTIVE; - 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 + // XXX pa->control= pnl_control; + // XXX panel_tabbed= group_tabbed= NULL; + // XXX pa->control= UI_PNL_TRANSP; // back to default if(pa->paneltab) return 0; if(pa->flag & PNL_CLOSED) return 0; @@ -249,16 +339,6 @@ int uiNewPanel(const bContext *C, ARegion *ar, uiBlock *block, char *panelname, return 1; } -Panel *uiPanelFromBlock(uiBlock *block) -{ - return block->panel; -} - -void uiFreePanels(ListBase *lb) -{ - BLI_freelistN(lb); -} - void uiNewPanelHeight(uiBlock *block, int sizey) { if(sizey<0) sizey= 0; @@ -282,7 +362,7 @@ static int panel_has_tabs(ARegion *ar, Panel *panel) if(panel==NULL) return 0; while(pa) { - if(pa->active && pa->paneltab==panel) { + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel) { return 1; } pa= pa->next; @@ -301,31 +381,28 @@ static void ui_scale_panel_block(uiBlock *block) /* buttons min/max centered, offset calculated */ ui_bounds_block(block); - 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; + if((!block->panel->type) && 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 ) ; + if((!block->panel->type) && (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) { + for(but= block->buttons.first; but; but=but->next) { 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 @@ -340,7 +417,7 @@ void uiPanelsHome(ARegion *ar) v2d= &ar->v2d; for(pa= ar->panels.first; pa; pa=pa->next) { - if(pa->active && pa->paneltab==NULL) { + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { done= 1; if(pa->ofsx < minx) minx= pa->ofsx; if(pa->ofsx+pa->sizex > maxx) maxx= pa->ofsx+pa->sizex; @@ -387,7 +464,7 @@ static void ui_panels_update_totrct(ARegion *ar) v2d->tot.ymin= -ar->winy; for(pa= ar->panels.first; pa; pa=pa->next) { - if(pa->active && pa->paneltab==NULL) { + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { done= 1; if(pa->ofsx < v2d->tot.xmin) @@ -414,6 +491,25 @@ static void ui_panels_update_totrct(ARegion *ar) UI_view2d_totRect_set(v2d, v2d->tot.xmax, v2d->tot.ymin); } +uiBlock *uiFindOpenPanelBlockName(ListBase *lb, char *name) +{ + uiBlock *block; + Panel *pa; + + for(block= lb->first; block; block= block->next) { + pa= block->panel; + + if(pa && (pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { + if(pa->flag & PNL_CLOSED); + else if(strncmp(name, pa->panelname, UI_MAX_NAME_STR)==0) break; + } + } + + return block; +} + +/**************************** drawing *******************************/ + /* extern used by previewrender */ void uiPanelPush(uiBlock *block) { @@ -428,27 +524,14 @@ 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; -} - /* triangle 'icon' for panel header */ void ui_draw_tria_icon(float x, float y, char dir) { if(dir=='h') { - ui_draw_anti_tria( x-1, y, x-1, y+11.0, x+9, y+6.25); + ui_draw_anti_tria(x-1, y, x-1, y+11.0, x+9, y+6.25); } else { - ui_draw_anti_tria( x-3, y+10, x+8-1, y+10, x+4.25-2, y); + ui_draw_anti_tria(x-3, y+10, x+8-1, y+10, x+4.25-2, y); } } @@ -469,8 +552,8 @@ void ui_draw_anti_x(float x1, float y1, float x2, float y2) { /* set antialias line */ - glEnable( GL_LINE_SMOOTH ); - glEnable( GL_BLEND ); + glEnable(GL_LINE_SMOOTH); + glEnable(GL_BLEND); glLineWidth(2.0); @@ -479,8 +562,8 @@ void ui_draw_anti_x(float x1, float y1, float x2, float y2) glLineWidth(1.0); - glDisable( GL_LINE_SMOOTH ); - glDisable( GL_BLEND ); + glDisable(GL_LINE_SMOOTH); + glDisable(GL_BLEND); } @@ -489,7 +572,7 @@ 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); + ui_draw_anti_x(x, y, x+9.375, y+9.375); } @@ -558,7 +641,7 @@ static void ui_draw_panel_header_style(ARegion *ar, uiStyle *style, uiBlock *blo /* count */ for(pa= ar->panels.first; pa; pa=pa->next) - if(pa->active) + if(pa->runtime_flag & PNL_ACTIVE) if(pa->paneltab==panel) nr++; @@ -583,7 +666,7 @@ static void ui_draw_panel_header_style(ARegion *ar, uiStyle *style, uiBlock *blo for(pa= ar->panels.first; pa; pa=pa->next) { panelname= pa->drawname[0]?pa->drawname:pa->panelname; - if(pa->active && (pa==panel || pa->paneltab==panel)) { + if((pa->runtime_flag & PNL_ACTIVE) && (pa==panel || pa->paneltab==panel)) { float col[3]; UI_GetThemeColor3fv(TH_TEXT, col); @@ -625,7 +708,7 @@ void ui_draw_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect) int ofsx; if(panel->paneltab) return; - + /* calculate header rect */ headrect= *rect; headrect.ymin= headrect.ymax; @@ -634,7 +717,7 @@ void ui_draw_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect) /* divider only when there's a previous panel */ prev= panel->prev; while(prev) { - if(prev->active) break; + if(prev->runtime_flag & PNL_ACTIVE) break; prev= prev->prev; } @@ -733,9 +816,7 @@ void ui_draw_panel(ARegion *ar, uiStyle *style, uiBlock *block, rcti *rect) } - -/* ------------ panel alignment ---------------- */ - +/************************** panel alignment *************************/ /* this function is needed because uiBlock and Panel itself dont change sizey or location when closed */ @@ -754,7 +835,6 @@ static int get_panel_real_ofsx(Panel *pa) else return pa->ofsx+pa->sizex; } - typedef struct PanelSort { Panel *pa, *orig; } PanelSort; @@ -769,10 +849,10 @@ 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; + 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; } @@ -782,10 +862,20 @@ static int find_highest_panel(const void *a1, const void *a2) { const PanelSort *ps1=a1, *ps2=a2; - if( ps1->pa->ofsy+ps1->pa->sizey < ps2->pa->ofsy+ps2->pa->sizey) return 1; - else if( ps1->pa->ofsy+ps1->pa->sizey > ps2->pa->ofsy+ps2->pa->sizey) return -1; - else if( ps1->pa->sortcounter > ps2->pa->sortcounter) return 1; - else if( ps1->pa->sortcounter < ps2->pa->sortcounter) return -1; + if(ps1->pa->ofsy+ps1->pa->sizey < ps2->pa->ofsy+ps2->pa->sizey) return 1; + else if(ps1->pa->ofsy+ps1->pa->sizey > ps2->pa->ofsy+ps2->pa->sizey) 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 compare_panel(const void *a1, const void *a2) +{ + const PanelSort *ps1=a1, *ps2=a2; + + if(ps1->pa->sortcounter > ps2->pa->sortcounter) return 1; + else if(ps1->pa->sortcounter < ps2->pa->sortcounter) return -1; return 0; } @@ -796,64 +886,61 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac) { Panel *pa; PanelSort *ps, *panelsort, *psnext; - static int sortcounter= 0; int a, tot=0, done; int align= panel_aligned(sa, ar); - /* count active, not tabbed Panels */ - for(pa= ar->panels.first; pa; pa= pa->next) { - if(pa->active && pa->paneltab==NULL) tot++; - } + /* count active, not tabbed panels */ + for(pa= ar->panels.first; pa; pa= pa->next) + if((pa->runtime_flag & PNL_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) && (align==BUT_VERTICAL) ) + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { + if((pa->flag & PNL_CLOSEDX) && (align==BUT_VERTICAL)) pa->flag ^= PNL_CLOSED; - - else if( (pa->flag & PNL_CLOSEDY) && (align==BUT_HORIZONTAL) ) + else if((pa->flag & PNL_CLOSEDY) && (align==BUT_HORIZONTAL)) pa->flag ^= PNL_CLOSED; - } } - panelsort= MEM_callocN( tot*sizeof(PanelSort), "panelsort"); + /* sort panels */ + 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) { + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==NULL) { ps->pa= MEM_dupallocN(pa); ps->orig= pa; ps++; } } +#if 0 if(align==BUT_VERTICAL) qsort(panelsort, tot, sizeof(PanelSort), find_highest_panel); else qsort(panelsort, tot, sizeof(PanelSort), find_leftmost_panel); +#endif + qsort(panelsort, tot, sizeof(PanelSort), compare_panel); /* no smart other default start loc! this keeps switching f5/f6/etc compatible */ ps= panelsort; ps->pa->ofsx= PNL_DIST; - if(align==BUT_VERTICAL) - ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST; - else - ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST; // XXX was 0; + ps->pa->ofsy= -ps->pa->sizey-PNL_HEADER-PNL_DIST; - for(a=0 ; a<tot-1; a++, ps++) { + for(a=0; a<tot-1; a++, ps++) { psnext= ps+1; if(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; + 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; + psnext->pa->ofsx= get_panel_real_ofsx(ps->pa)+PNL_DIST; + psnext->pa->ofsy= ps->pa->ofsy + ps->pa->sizey - psnext->pa->sizey; } } @@ -871,17 +958,9 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac) } /* 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; + if(pa->paneltab && (pa->runtime_flag & PNL_ACTIVE)) + ui_panel_copy_offset(pa, pa->paneltab); /* free panelsort array */ for(ps= panelsort, a=0; a<tot; a++, ps++) @@ -892,7 +971,7 @@ int uiAlignPanelStep(ScrArea *sa, ARegion *ar, float fac) } -static void ui_do_animate(bContext *C, Panel *panel) +static void ui_do_animate(const bContext *C, Panel *panel) { uiHandlePanelData *data= panel->activedata; ScrArea *sa= CTX_wm_area(C); @@ -909,7 +988,7 @@ static void ui_do_animate(bContext *C, Panel *panel) else fac= 1.0f; - if(fac == 1.0f) { + if(fac >= 1.0f) { panel_activate_state(C, panel, PANEL_STATE_EXIT); return; } @@ -921,8 +1000,12 @@ void uiBeginPanels(const bContext *C, ARegion *ar) /* set all panels as inactive, so that at the end we know * which ones were used */ - for(pa=ar->panels.first; pa; pa=pa->next) - pa->active= 0; + for(pa=ar->panels.first; pa; pa=pa->next) { + if(pa->runtime_flag & PNL_ACTIVE) + pa->runtime_flag= PNL_WAS_ACTIVE; + else + pa->runtime_flag= 0; + } } /* only draws blocks with panels */ @@ -930,7 +1013,7 @@ void uiEndPanels(const bContext *C, ARegion *ar) { ScrArea *sa= CTX_wm_area(C); uiBlock *block; - Panel *panot, *panew, *patest; + Panel *panot, *panew, *patest, *pa; /* scaling contents */ for(block= ar->uiblocks.first; block; block= block->next) @@ -939,10 +1022,10 @@ void uiEndPanels(const bContext *C, ARegion *ar) /* consistancy; are panels not made, whilst they have tabs */ for(panot= ar->panels.first; panot; panot= panot->next) { - if(panot->active==0) { // not made + if((panot->runtime_flag & PNL_ACTIVE)==0) { // not made for(panew= ar->panels.first; panew; panew= panew->next) { - if(panew->active) { + if((panew->runtime_flag & PNL_ACTIVE)) { if(panew->paneltab==panot) { // panew is tab in notmade pa break; } @@ -962,9 +1045,13 @@ void uiEndPanels(const bContext *C, ARegion *ar) } } - /* re-align */ - if(panels_re_align(sa, ar)) - uiAlignPanelStep(sa, ar, 1.0); + /* re-align, possibly with animation */ + if(panels_re_align(sa, ar, &pa)) { + if(pa) + panel_activate_state(C, pa, PANEL_STATE_ANIMATION); + else + uiAlignPanelStep(sa, ar, 1.0); + } if(sa->spacetype!=SPACE_BUTS) { #if 0 // XXX make float panel exception @@ -1017,7 +1104,7 @@ void uiEndPanels(const bContext *C, ARegion *ar) 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 + 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)) { @@ -1032,7 +1119,7 @@ void uiEndPanels(const bContext *C, ARegion *ar) 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 + if(miny + dy < 0.0) dy= -miny; // when panel cant fit, put it fixed here block->panel->ofsx+= dx/sl->blockscale; @@ -1040,7 +1127,7 @@ void uiEndPanels(const bContext *C, ARegion *ar) /* copy locations */ for(patest= ar->panels.first; patest; patest= patest->next) { - if(patest->paneltab==block->panel) copy_panel_offset(patest, block->panel); + if(patest->paneltab==block->panel) ui_panel_copy_offset(patest, block->panel); } } @@ -1078,18 +1165,18 @@ static void check_panel_overlap(ARegion *ar, Panel *panel) for(pa=ar->panels.first; pa; pa=pa->next) { pa->flag &= ~PNL_OVERLAP; if(panel && (pa != panel)) { - if(pa->paneltab==NULL && pa->active) { + if(pa->paneltab==NULL && (pa->runtime_flag & PNL_ACTIVE)) { float safex= 0.2, safey= 0.2; - if( pa->flag & PNL_CLOSEDX) safex= 0.05; + 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_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) + 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; } } @@ -1103,7 +1190,7 @@ static void test_add_new_tabs(ARegion *ar) pa= ar->panels.first; while(pa) { - if(pa->active) { + if(pa->runtime_flag & PNL_ACTIVE) { if(pa->flag & PNL_SELECT) pasel= pa; if(pa->flag & PNL_OVERLAP) palap= pa; } @@ -1116,7 +1203,7 @@ static void test_add_new_tabs(ARegion *ar) pa= ar->panels.first; while(pa) { if(pa->paneltab==pasel) { - copy_panel_offset(pa, pasel); + ui_panel_copy_offset(pa, pasel); } pa= pa->next; } @@ -1128,13 +1215,13 @@ static void test_add_new_tabs(ARegion *ar) palap->paneltab= pasel; /* the selected panel gets coords of overlapped one */ - copy_panel_offset(pasel, palap); + ui_panel_copy_offset(pasel, palap); /* and its tabs */ pa= ar->panels.first; while(pa) { if(pa->paneltab == pasel) { - copy_panel_offset(pa, palap); + ui_panel_copy_offset(pa, palap); } pa= pa->next; } @@ -1149,9 +1236,9 @@ static void test_add_new_tabs(ARegion *ar) } } -/* ------------ panel drag ---------------- */ +/************************ panel dragging ****************************/ -static void ui_do_drag(bContext *C, wmEvent *event, Panel *panel) +static void ui_do_drag(const bContext *C, wmEvent *event, Panel *panel) { uiHandlePanelData *data= panel->activedata; ScrArea *sa= CTX_wm_area(C); @@ -1168,13 +1255,11 @@ static void ui_do_drag(bContext *C, wmEvent *event, Panel *panel) if(data->state == PANEL_STATE_DRAG_SCALE) { panel->sizex = MAX2(data->startsizex+dx, UI_PANEL_MINX); - if(data->startsizey-dy < UI_PANEL_MINY) { + if(data->startsizey-dy < UI_PANEL_MINY) dy= -UI_PANEL_MINY+data->startsizey; - } - panel->sizey = data->startsizey-dy; - - panel->ofsy= data->startofsy+dy; + panel->sizey= data->startsizey-dy; + panel->ofsy= data->startofsy+dy; } else { /* reset the panel snapping, to allow dragging away from snapped edges */ @@ -1190,7 +1275,7 @@ static void ui_do_drag(bContext *C, wmEvent *event, Panel *panel) ED_region_tag_redraw(ar); } -static void ui_do_untab(bContext *C, wmEvent *event, Panel *panel) +static void ui_do_untab(const bContext *C, wmEvent *event, Panel *panel) { uiHandlePanelData *data= panel->activedata; ARegion *ar= CTX_wm_region(C); @@ -1219,20 +1304,20 @@ static void ui_do_untab(bContext *C, wmEvent *event, Panel *panel) } } -/* region level panel interaction */ +/******************* region level panel interaction *****************/ -static void panel_clicked_tabs(bContext *C, ScrArea *sa, ARegion *ar, uiBlock *block, int mousex) +static void panel_clicked_tabs(const 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; + if(block->panel->type && (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) + if((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel) nr++; if(nr==1) return; @@ -1242,8 +1327,8 @@ static void panel_clicked_tabs(bContext *C, ScrArea *sa, ARegion *ar, uiBlock *b 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) ) { + if(pa==panel || ((pa->runtime_flag & PNL_ACTIVE) && pa->paneltab==panel)) { + if((mousex > ofsx+a*width) && (mousex < ofsx+(a+1)*width)) { tabsel= pa; break; } @@ -1269,8 +1354,8 @@ static void panel_clicked_tabs(bContext *C, ScrArea *sa, ARegion *ar, uiBlock *b /* copy locations to tabs */ for(pa= ar->panels.first; pa; pa= pa->next) { - if(pa->paneltab && pa->active) { - copy_panel_offset(pa, pa->paneltab); + if(pa->paneltab && pa->runtime_flag & PNL_ACTIVE) { + ui_panel_copy_offset(pa, pa->paneltab); } } @@ -1286,7 +1371,7 @@ static void panel_clicked_tabs(bContext *C, ScrArea *sa, ARegion *ar, uiBlock *b /* 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) +static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, int my) { ScrArea *sa= CTX_wm_area(C); ARegion *ar= CTX_wm_region(C); @@ -1441,7 +1526,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event) return retval; } -/* window level modal panel interaction */ +/**************** window level modal panel interaction **************/ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata) { @@ -1489,7 +1574,7 @@ static void ui_handler_remove_panel(bContext *C, void *userdata) panel_activate_state(C, pa, PANEL_STATE_EXIT); } -static void panel_activate_state(bContext *C, Panel *pa, uiHandlePanelState state) +static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state) { uiHandlePanelData *data= pa->activedata; wmWindow *win= CTX_wm_window(C); diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c index fdda139ff9b..884e5bee615 100644 --- a/source/blender/editors/interface/interface_utils.c +++ b/source/blender/editors/interface/interface_utils.c @@ -297,7 +297,7 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) char *name; int x= 0, y= 0; - layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, DEF_BUT_WIDTH*2, 0); + layout= uiLayoutBegin(UI_LAYOUT_VERTICAL, x, y, DEF_BUT_WIDTH*2, 20); uiLayoutColumn(layout); uiItemL(layout, (char*)RNA_struct_ui_name(ptr), 0); @@ -314,7 +314,9 @@ int uiDefAutoButsRNA(const bContext *C, uiBlock *block, PointerRNA *ptr) uiLayoutSplit(layout, 2, 0); name= (char*)RNA_property_ui_name(ptr, prop); + uiLayoutColumn(uiLayoutSub(layout, 0)); uiItemL(uiLayoutSub(layout, 0), name, 0); + uiLayoutColumn(uiLayoutSub(layout, 1)); uiItemFullR(uiLayoutSub(layout, 1), "", 0, ptr, prop, -1, 0); } diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 5588343d223..018b328836a 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -70,6 +70,7 @@ static SpaceLink *buttons_new(const bContext *C) sbuts= MEM_callocN(sizeof(SpaceButs), "initbuts"); sbuts->spacetype= SPACE_BUTS; sbuts->scaflag= BUTS_SENS_LINK|BUTS_SENS_ACT|BUTS_CONT_ACT|BUTS_ACT_ACT|BUTS_ACT_LINK; + sbuts->align= BUT_AUTO; /* header */ ar= MEM_callocN(sizeof(ARegion), "header for buts"); @@ -128,7 +129,15 @@ static void buttons_free(SpaceLink *sl) /* spacetype; init callback */ static void buttons_init(struct wmWindowManager *wm, ScrArea *sa) { - + SpaceButs *sbuts= sa->spacedata.first; + + /* auto-align based on size */ + if(sbuts->align == BUT_AUTO) { + if(sa->winx > sa->winy) + sbuts->align= BUT_HORIZONTAL; + else + sbuts->align= BUT_VERTICAL; + } } static SpaceLink *buttons_duplicate(SpaceLink *sl) @@ -158,18 +167,14 @@ 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); + int vertical= (sbuts->align == BUT_VERTICAL); + int tab= sbuts->tab[sbuts->mainb]; if(sbuts->mainb == CONTEXT_OBJECT) { - int tab= sbuts->tab[CONTEXT_OBJECT]; - int vertical= (sbuts->align == 2); - if(tab == TAB_OBJECT_OBJECT) uiRegionPanelLayout(C, ar, vertical, "object"); } else if (sbuts->mainb == CONTEXT_SCENE){ - int tab= sbuts->tab[CONTEXT_SCENE]; - int vertical= (sbuts->align == 2); - if(tab == TAB_SCENE_RENDER) uiRegionPanelLayout(C, ar, vertical, "render"); } diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 4ab9aa55b42..89532ad13b4 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -96,7 +96,7 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */ char panelname[64], tabname[64]; /* defined as UI_MAX_NAME_STR */ char drawname[64]; /* panelname is identifier for restoring location */ short ofsx, ofsy, sizex, sizey; - short flag, active; /* active= used currently by a uiBlock */ + short flag, runtime_flag; short control; short snap; int sortcounter, pad; /* when sorting panels, it uses this to put new ones in right place */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 5387aa90072..a3dc657217a 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -467,8 +467,10 @@ typedef struct SpaceImaSel { #define SB_PRV_OSA 1 /* sbuts->align */ +#define BUT_FREE 0 #define BUT_HORIZONTAL 1 #define BUT_VERTICAL 2 +#define BUT_AUTO 3 /* sbuts->scaflag */ #define BUTS_SENS_SEL 1 diff --git a/source/blender/python/intern/bpy_panel_wrap.c b/source/blender/python/intern/bpy_panel_wrap.c index 8cdac286f8d..b79d3259e56 100644 --- a/source/blender/python/intern/bpy_panel_wrap.c +++ b/source/blender/python/intern/bpy_panel_wrap.c @@ -36,6 +36,8 @@ #include "DNA_screen_types.h" #include "MEM_guardedalloc.h" #include "ED_screen.h" +#include "WM_api.h" +#include "WM_types.h" #define PYPANEL_ATTR_UINAME "__label__" #define PYPANEL_ATTR_IDNAME "__name__" /* use pythons class name */ @@ -125,11 +127,13 @@ static int PyPanel_poll(const bContext *C) /* pyOperators - Operators defined IN Python */ PyObject *PyPanel_wrap_add(PyObject *self, PyObject *args) { + bContext *C; PyObject *item; PyObject *py_class; PyObject *base_class; char *space_identifier; char *region_identifier; + char *idname; int space_value; int region_value; @@ -204,27 +208,39 @@ PyObject *PyPanel_wrap_add(PyObject *self, PyObject *args) return NULL; } - pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); - pt->idname= _PyUnicode_AsString(pypnl_class_attrs[PYPANEL_ATTR_IDNAME_IDX]); + idname= _PyUnicode_AsString(pypnl_class_attrs[PYPANEL_ATTR_IDNAME_IDX]); - item= pypnl_class_attrs[PYPANEL_ATTR_UINAME_IDX]; - pt->name= item ? _PyUnicode_AsString(item):pt->idname; + for(pt=art->paneltypes.first; pt; pt=pt->next) + if(strcmp(pt->idname, idname) == 0) + break; + + if(!pt) { + pt= MEM_callocN(sizeof(PanelType), "python buttons panel"); + pt->srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); + BLI_addtail(&art->paneltypes, pt); + } + + pt->idname= idname; + item= pypnl_class_attrs[PYPANEL_ATTR_UINAME_IDX]; + pt->name= item? _PyUnicode_AsString(item): pt->idname; pt->context= _PyUnicode_AsString(pypnl_class_attrs[PYPANEL_ATTR_CONTEXT_IDX]); if (pypnl_class_attrs[PYPANEL_ATTR_POLL_IDX]) pt->poll= PyPanel_poll; + else + pt->poll= NULL; pt->draw= PyPanel_draw; Py_INCREF(py_class); pt->py_data= (void *)py_class; - - BLI_addtail(&art->paneltypes, pt); - - pt->srna= RNA_def_struct(&BLENDER_RNA, pt->idname, "Panel"); RNA_struct_py_type_set(pt->srna, py_class); + C= (bContext *)PyCObject_AsVoidPtr(PyDict_GetItemString(PyEval_GetGlobals(), "__bpy_context__")); + if(C) + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); + Py_RETURN_NONE; } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 31bebc70dd0..b40b8e93150 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -92,7 +92,7 @@ struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); -struct wmEventHandler *WM_event_add_ui_handler(struct bContext *C, ListBase *handlers, +struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata); void WM_event_remove_ui_handler(ListBase *handlers, diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 283f0819996..e142a5f9640 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1196,7 +1196,7 @@ void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap) } } -wmEventHandler *WM_event_add_ui_handler(bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata) +wmEventHandler *WM_event_add_ui_handler(const bContext *C, ListBase *handlers, wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata) { wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event ui handler"); handler->ui_handle= func; |