From a9b97dcf22be451ec5b8229d799a2f74f705be18 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 4 Dec 2013 11:54:56 +1100 Subject: User interface: internal change, collect panels to draw before drawing. avoids calling poll twice, in some cases --- source/blender/blenlib/BLI_linklist_stack.h | 11 +++ source/blender/editors/screen/area.c | 111 ++++++++++++++++------------ 2 files changed, 73 insertions(+), 49 deletions(-) diff --git a/source/blender/blenlib/BLI_linklist_stack.h b/source/blender/blenlib/BLI_linklist_stack.h index c9fb00ecdf5..ef78fb9a305 100644 --- a/source/blender/blenlib/BLI_linklist_stack.h +++ b/source/blender/blenlib/BLI_linklist_stack.h @@ -147,6 +147,17 @@ (_BLI_SMALLSTACK_CAST(var) ((_##var##_stack) ? \ (_BLI_SMALLSTACK_DEL(var), (_##var##_free->link)) : NULL)) +/* loop over stack members last-added-first */ +#define BLI_SMALLSTACK_ITER_BEGIN(var, item) \ + { \ + LinkNode *_##var##_iter; \ + for (_##var##_iter = _##var##_stack; _##var##_iter; _##var##_iter = _##var##_iter->next) { \ + item = _BLI_SMALLSTACK_CAST(var) (_##var##_iter->link); \ + +#define BLI_SMALLSTACK_ITER_END \ + } \ + } (void)0 + #define BLI_SMALLSTACK_FREE(var) { \ (void)&(_##var##_type); \ } (void)0 diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 2caf318379b..29127afef45 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -39,6 +39,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" #include "BLI_utildefines.h" +#include "BLI_linklist_stack.h" #include "BLF_translation.h" @@ -1571,6 +1572,8 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * int redo; int scroll; + BLI_SMALLSTACK_DECLARE(pt_stack, PanelType *); + if (contextnr >= 0) is_context_new = UI_view2d_tab_set(v2d, contextnr); @@ -1592,7 +1595,22 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } scroll = v2d->scroll; - + + + /* collect panels to draw */ + for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) { + /* verify context */ + if (context && pt->context[0] && !STREQ(context, pt->context)) { + continue; + } + + /* draw panel */ + if (pt->draw && (!pt->poll || pt->poll(C, pt))) { + BLI_SMALLSTACK_PUSH(pt_stack, pt); + } + } + + /* sortof hack - but we cannot predict the height of panels, until it's being generated */ /* the layout engine works with fixed width (from v2d->cur), which is being set at end of the loop */ /* in case scroller settings (hide flags) differ from previous, the whole loop gets done again */ @@ -1613,63 +1631,57 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * /* set view2d view matrix - uiBeginBlock() stores it */ UI_view2d_view_ortho(v2d); - for (pt = ar->type->paneltypes.first; pt; pt = pt->next) { - /* verify context */ - if (context) - if (pt->context[0] && strcmp(context, pt->context) != 0) - continue; + BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt) + { + block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); + panel = uiBeginPanel(sa, ar, block, pt, &open); - /* draw panel */ - if (pt->draw && (!pt->poll || pt->poll(C, pt))) { - block = uiBeginBlock(C, ar, pt->idname, UI_EMBOSS); - panel = uiBeginPanel(sa, ar, block, pt, &open); + /* bad fixed values */ + triangle = (int)(UI_UNIT_Y * 1.1f); - /* bad fixed values */ - triangle = (int)(UI_UNIT_Y * 1.1f); + if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { + /* for enabled buttons */ + panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, + triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); - if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) { - /* for enabled buttons */ - panel->layout = uiBlockLayout(block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, - triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, style); + pt->draw_header(C, panel); - pt->draw_header(C, panel); + uiBlockLayoutResolve(block, &xco, &yco); + panel->labelofs = xco - triangle; + panel->layout = NULL; + } + else { + panel->labelofs = 0; + } - uiBlockLayoutResolve(block, &xco, &yco); - panel->labelofs = xco - triangle; - panel->layout = NULL; - } - else { - panel->labelofs = 0; - } + if (open) { + short panelContext; - if (open) { - short panelContext; - - /* panel context can either be toolbar region or normal panels region */ - if (ar->regiontype == RGN_TYPE_TOOLS) - panelContext = UI_LAYOUT_TOOLBAR; - else - panelContext = UI_LAYOUT_PANEL; - - panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext, - style->panelspace, 0, w - 2 * style->panelspace, em, style); - - pt->draw(C, panel); - - uiBlockLayoutResolve(block, &xco, &yco); - panel->layout = NULL; - - yco -= 2 * style->panelspace; - uiEndPanel(block, w, -yco); - } - else { - yco = 0; - uiEndPanel(block, w, 0); - } + /* panel context can either be toolbar region or normal panels region */ + if (ar->regiontype == RGN_TYPE_TOOLS) + panelContext = UI_LAYOUT_TOOLBAR; + else + panelContext = UI_LAYOUT_PANEL; - uiEndBlock(C, block); + panel->layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, panelContext, + style->panelspace, 0, w - 2 * style->panelspace, em, style); + + pt->draw(C, panel); + + uiBlockLayoutResolve(block, &xco, &yco); + panel->layout = NULL; + + yco -= 2 * style->panelspace; + uiEndPanel(block, w, -yco); } + else { + yco = 0; + uiEndPanel(block, w, 0); + } + + uiEndBlock(C, block); } + BLI_SMALLSTACK_ITER_END; /* align panels and return size */ uiEndPanels(C, ar, &x, &y); @@ -1706,6 +1718,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, int vertical, const char * } } + BLI_SMALLSTACK_FREE(pt_stack); /* clear */ if (ar->overlap) { -- cgit v1.2.3