UI: add subpanel support.
In the Python API, any panel becomes a subpanel by setting bl_parent_id to the name of the parent panel. These subpanels can contain advanced or less commonly used settings.
This commit is contained in:
parent
9b01e7bc27
commit
d7c2b78822
|
@ -28,7 +28,7 @@
|
|||
* and keep comment above the defines.
|
||||
* Use STRINGIFY() rather than defining with quotes */
|
||||
#define BLENDER_VERSION 280
|
||||
#define BLENDER_SUBVERSION 16
|
||||
#define BLENDER_SUBVERSION 17
|
||||
/* Several breakages with 270, e.g. constraint deg vs rad */
|
||||
#define BLENDER_MINVERSION 270
|
||||
#define BLENDER_MINSUBVERSION 6
|
||||
|
|
|
@ -205,7 +205,8 @@ typedef struct PanelType {
|
|||
char translation_context[BKE_ST_MAXNAME];
|
||||
char context[BKE_ST_MAXNAME]; /* for buttons window */
|
||||
char category[BKE_ST_MAXNAME]; /* for category tabs */
|
||||
char owner_id[BKE_ST_MAXNAME]; /* for work-spaces to selectively show. */
|
||||
char owner_id[BKE_ST_MAXNAME]; /* for work-spaces to selectively show. */
|
||||
char parent_id[BKE_ST_MAXNAME]; /* parent idname for subpanels */
|
||||
int space_type;
|
||||
int region_type;
|
||||
|
||||
|
@ -218,6 +219,10 @@ typedef struct PanelType {
|
|||
/* draw entirely, view changes should be handled here */
|
||||
void (*draw)(const struct bContext *C, struct Panel *pa);
|
||||
|
||||
/* sub panels */
|
||||
struct PanelType *parent;
|
||||
ListBase children;
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA ext;
|
||||
} PanelType;
|
||||
|
|
|
@ -69,13 +69,19 @@ static void spacetype_free(SpaceType *st)
|
|||
for (art = st->regiontypes.first; art; art = art->next) {
|
||||
BLI_freelistN(&art->drawcalls);
|
||||
|
||||
for (pt = art->paneltypes.first; pt; pt = pt->next)
|
||||
if (pt->ext.free)
|
||||
for (pt = art->paneltypes.first; pt; pt = pt->next) {
|
||||
if (pt->ext.free) {
|
||||
pt->ext.free(pt->ext.data);
|
||||
}
|
||||
|
||||
for (ht = art->headertypes.first; ht; ht = ht->next)
|
||||
if (ht->ext.free)
|
||||
BLI_freelistN(&pt->children);
|
||||
}
|
||||
|
||||
for (ht = art->headertypes.first; ht; ht = ht->next) {
|
||||
if (ht->ext.free) {
|
||||
ht->ext.free(ht->ext.data);
|
||||
}
|
||||
}
|
||||
|
||||
BLI_freelistN(&art->paneltypes);
|
||||
BLI_freelistN(&art->headertypes);
|
||||
|
@ -169,10 +175,35 @@ void BKE_spacedata_freelist(ListBase *lb)
|
|||
BLI_freelistN(lb);
|
||||
}
|
||||
|
||||
static void panel_list_copy(ListBase *newlb, const ListBase *lb)
|
||||
{
|
||||
BLI_listbase_clear(newlb);
|
||||
BLI_duplicatelist(newlb, lb);
|
||||
|
||||
/* copy panel pointers */
|
||||
Panel *newpa = newlb->first;
|
||||
Panel *pa = lb->first;
|
||||
for (; newpa; newpa = newpa->next, pa = pa->next) {
|
||||
newpa->activedata = NULL;
|
||||
|
||||
Panel *newpatab = newlb->first;
|
||||
Panel *patab = lb->first;
|
||||
while (newpatab) {
|
||||
if (newpa->paneltab == patab) {
|
||||
newpa->paneltab = newpatab;
|
||||
break;
|
||||
}
|
||||
newpatab = newpatab->next;
|
||||
patab = patab->next;
|
||||
}
|
||||
|
||||
panel_list_copy(&newpa->children, &pa->children);
|
||||
}
|
||||
}
|
||||
|
||||
ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
|
||||
{
|
||||
ARegion *newar = MEM_dupallocN(ar);
|
||||
Panel *pa, *newpa, *patab;
|
||||
|
||||
newar->prev = newar->next = NULL;
|
||||
BLI_listbase_clear(&newar->handlers);
|
||||
|
@ -199,25 +230,10 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
|
|||
if (ar->v2d.tab_offset)
|
||||
newar->v2d.tab_offset = MEM_dupallocN(ar->v2d.tab_offset);
|
||||
|
||||
BLI_listbase_clear(&newar->panels);
|
||||
BLI_duplicatelist(&newar->panels, &ar->panels);
|
||||
panel_list_copy(&newar->panels, &ar->panels);
|
||||
|
||||
BLI_listbase_clear(&newar->ui_previews);
|
||||
BLI_duplicatelist(&newar->ui_previews, &ar->ui_previews);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -329,6 +345,19 @@ void BKE_region_callback_free_manipulatormap_set(void (*callback)(struct wmManip
|
|||
region_free_manipulatormap_callback = callback;
|
||||
}
|
||||
|
||||
static void panel_list_free(ListBase *lb)
|
||||
{
|
||||
Panel *pa, *pa_next;
|
||||
for (pa = lb->first; pa; pa = pa_next) {
|
||||
pa_next = pa->next;
|
||||
if (pa->activedata) {
|
||||
MEM_freeN(pa->activedata);
|
||||
}
|
||||
panel_list_free(&pa->children);
|
||||
MEM_freeN(pa);
|
||||
}
|
||||
}
|
||||
|
||||
/* not region itself */
|
||||
void BKE_area_region_free(SpaceType *st, ARegion *ar)
|
||||
{
|
||||
|
@ -351,16 +380,7 @@ void BKE_area_region_free(SpaceType *st, ARegion *ar)
|
|||
ar->v2d.tab_offset = NULL;
|
||||
}
|
||||
|
||||
if (!BLI_listbase_is_empty(&ar->panels)) {
|
||||
Panel *pa, *pa_next;
|
||||
for (pa = ar->panels.first; pa; pa = pa_next) {
|
||||
pa_next = pa->next;
|
||||
if (pa->activedata) {
|
||||
MEM_freeN(pa->activedata);
|
||||
}
|
||||
MEM_freeN(pa);
|
||||
}
|
||||
}
|
||||
panel_list_free(&ar->panels);
|
||||
|
||||
for (uilst = ar->ui_lists.first; uilst; uilst = uilst->next) {
|
||||
if (uilst->dyn_data) {
|
||||
|
|
|
@ -6396,19 +6396,24 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
|
|||
|
||||
/* *********** READ AREA **************** */
|
||||
|
||||
static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
static void direct_link_panel_list(FileData *fd, ListBase *lb)
|
||||
{
|
||||
Panel *pa;
|
||||
uiList *ui_list;
|
||||
link_list(fd, lb);
|
||||
|
||||
link_list(fd, &ar->panels);
|
||||
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
for (Panel *pa = lb->first; pa; pa = pa->next) {
|
||||
pa->paneltab = newdataadr(fd, pa->paneltab);
|
||||
pa->runtime_flag = 0;
|
||||
pa->activedata = NULL;
|
||||
pa->type = NULL;
|
||||
direct_link_panel_list(fd, &pa->children);
|
||||
}
|
||||
}
|
||||
|
||||
static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
|
||||
{
|
||||
uiList *ui_list;
|
||||
|
||||
direct_link_panel_list(fd, &ar->panels);
|
||||
|
||||
link_list(fd, &ar->panels_category_active);
|
||||
|
||||
|
|
|
@ -2762,14 +2762,19 @@ static void write_soops(WriteData *wd, SpaceOops *so)
|
|||
}
|
||||
}
|
||||
|
||||
static void write_panel_list(WriteData *wd, ListBase *lb)
|
||||
{
|
||||
for (Panel *pa = lb->first; pa; pa = pa->next) {
|
||||
writestruct(wd, DATA, Panel, 1, pa);
|
||||
write_panel_list(wd, &pa->children);
|
||||
}
|
||||
}
|
||||
|
||||
static void write_area_regions(WriteData *wd, ScrArea *area)
|
||||
{
|
||||
for (ARegion *region = area->regionbase.first; region; region = region->next) {
|
||||
write_region(wd, region, area->spacetype);
|
||||
|
||||
for (Panel *pa = region->panels.first; pa; pa = pa->next) {
|
||||
writestruct(wd, DATA, Panel, 1, pa);
|
||||
}
|
||||
write_panel_list(wd, ®ion->panels);
|
||||
|
||||
for (PanelCategoryStack *pc_act = region->panels_category_active.first; pc_act; pc_act = pc_act->next) {
|
||||
writestruct(wd, DATA, PanelCategoryStack, 1, pc_act);
|
||||
|
|
|
@ -491,8 +491,6 @@ void UI_blocklist_update_window_matrix(const struct bContext *C, const struct Li
|
|||
void UI_blocklist_draw(const struct bContext *C, const struct ListBase *lb);
|
||||
void UI_block_update_from_old(const struct bContext *C, struct uiBlock *block);
|
||||
|
||||
uiBlock *UI_block_find_in_region(const char *name, struct ARegion *ar);
|
||||
|
||||
void UI_block_emboss_set(uiBlock *block, char dt);
|
||||
|
||||
void UI_block_free(const struct bContext *C, uiBlock *block);
|
||||
|
@ -824,9 +822,10 @@ void UI_panels_begin(const struct bContext *C, struct ARegion *ar);
|
|||
void UI_panels_end(const struct bContext *C, struct ARegion *ar, int *x, int *y);
|
||||
void UI_panels_draw(const struct bContext *C, struct ARegion *ar);
|
||||
|
||||
struct Panel *UI_panel_find_by_type(struct ARegion *ar, struct PanelType *pt);
|
||||
struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, uiBlock *block,
|
||||
struct PanelType *pt, struct Panel *pa, bool *r_open);
|
||||
struct Panel *UI_panel_find_by_type(struct ListBase *lb, struct PanelType *pt);
|
||||
struct Panel *UI_panel_begin(struct ScrArea *sa, struct ARegion *ar, struct ListBase *lb,
|
||||
uiBlock *block, struct PanelType *pt, struct Panel *pa,
|
||||
bool *r_open);
|
||||
void UI_panel_end(uiBlock *block, int width, int height);
|
||||
void UI_panels_scale(struct ARegion *ar, float new_width);
|
||||
|
||||
|
|
|
@ -74,6 +74,7 @@ typedef enum ThemeColorID {
|
|||
/* panels */
|
||||
TH_PANEL_HEADER,
|
||||
TH_PANEL_BACK,
|
||||
TH_PANEL_SUB_BACK,
|
||||
TH_PANEL_SHOW_HEADER,
|
||||
TH_PANEL_SHOW_BACK,
|
||||
|
||||
|
|
|
@ -2814,11 +2814,6 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, sh
|
|||
return block;
|
||||
}
|
||||
|
||||
uiBlock *UI_block_find_in_region(const char *name, ARegion *ar)
|
||||
{
|
||||
return BLI_findstring(&ar->uiblocks, name, offsetof(uiBlock, name));
|
||||
}
|
||||
|
||||
void UI_block_emboss_set(uiBlock *block, char dt)
|
||||
{
|
||||
block->dt = dt;
|
||||
|
|
|
@ -110,6 +110,7 @@ typedef struct uiHandlePanelData {
|
|||
int startsizex, startsizey;
|
||||
} uiHandlePanelData;
|
||||
|
||||
static int get_panel_real_size_y(Panel *pa);
|
||||
static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelState state);
|
||||
|
||||
/*********************** space specific code ************************/
|
||||
|
@ -133,45 +134,80 @@ static int panel_aligned(ScrArea *sa, ARegion *ar)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int panels_re_align(ScrArea *sa, ARegion *ar, Panel **r_pa)
|
||||
static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, bool *no_animation)
|
||||
{
|
||||
Panel *pa;
|
||||
int active = 0;
|
||||
for (Panel *pa = lb->first; pa; pa = pa->next) {
|
||||
/* Detect panel active flag changes. */
|
||||
if (!(pa->type && pa->type->parent)) {
|
||||
if ((pa->runtime_flag & PNL_WAS_ACTIVE) && !(pa->runtime_flag & PNL_ACTIVE)) {
|
||||
return true;
|
||||
}
|
||||
if (!(pa->runtime_flag & PNL_WAS_ACTIVE) && (pa->runtime_flag & PNL_ACTIVE)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
*r_pa = NULL;
|
||||
if ((pa->runtime_flag & PNL_ACTIVE) && !(pa->flag & PNL_CLOSED)) {
|
||||
if (panel_active_animation_changed(&pa->children, pa_animation, no_animation)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/* Detect animation. */
|
||||
if (pa->activedata) {
|
||||
uiHandlePanelData *data = pa->activedata;
|
||||
if (data->state == PANEL_STATE_ANIMATION) {
|
||||
*pa_animation = pa;
|
||||
}
|
||||
else {
|
||||
/* Don't animate while handling other interaction. */
|
||||
*no_animation = true;
|
||||
}
|
||||
}
|
||||
if ((pa->runtime_flag & PNL_ANIM_ALIGN) && !(*pa_animation)) {
|
||||
*pa_animation = pa;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool panels_need_realign(ScrArea *sa, ARegion *ar, Panel **pa_animate)
|
||||
{
|
||||
*pa_animate = 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)
|
||||
return 1;
|
||||
}
|
||||
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW)
|
||||
return 1;
|
||||
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS)
|
||||
return 1;
|
||||
|
||||
/* in case panel is added or disappears */
|
||||
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;
|
||||
}
|
||||
|
||||
/* in case we need to do an animation (size changes) */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->runtime_flag & PNL_ANIM_ALIGN) {
|
||||
if (!active)
|
||||
*r_pa = pa;
|
||||
return 1;
|
||||
if (sbuts->align) {
|
||||
if (sbuts->re_align || sbuts->mainbo != sbuts->mainb) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (sa->spacetype == SPACE_IMAGE && ar->regiontype == RGN_TYPE_PREVIEW) {
|
||||
return true;
|
||||
}
|
||||
else if (sa->spacetype == SPACE_FILE && ar->regiontype == RGN_TYPE_CHANNELS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Detect if a panel was added or removed. */
|
||||
Panel *pa_animation = NULL;
|
||||
bool no_animation = false;
|
||||
if (panel_active_animation_changed(&ar->panels, &pa_animation, &no_animation)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Detect panel marked for animation, if we're not already animating. */
|
||||
if (pa_animation) {
|
||||
if (!no_animation) {
|
||||
*pa_animate = pa_animation;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************** panels ******************************/
|
||||
|
@ -215,14 +251,14 @@ static void ui_panel_copy_offset(Panel *pa, Panel *papar)
|
|||
*/
|
||||
/* #define UI_USE_PANELTAB */
|
||||
|
||||
Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
|
||||
Panel *UI_panel_find_by_type(ListBase *lb, PanelType *pt)
|
||||
{
|
||||
Panel *pa;
|
||||
const char *idname = pt->idname;
|
||||
|
||||
#ifdef UI_USE_PANELTAB
|
||||
const char *tabname = pt->idname;
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
for (pa = lb->first; pa; pa = pa->next) {
|
||||
if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
|
||||
if (STREQLEN(pa->tabname, tabname, sizeof(pa->tabname))) {
|
||||
return pa;
|
||||
|
@ -230,7 +266,7 @@ Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
|
|||
}
|
||||
}
|
||||
#else
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
for (pa = lb->first; pa; pa = pa->next) {
|
||||
if (STREQLEN(pa->panelname, idname, sizeof(pa->panelname))) {
|
||||
return pa;
|
||||
}
|
||||
|
@ -243,7 +279,7 @@ Panel *UI_panel_find_by_type(ARegion *ar, PanelType *pt)
|
|||
/**
|
||||
* \note \a pa should be return value from #UI_panel_find_by_type and can be NULL.
|
||||
*/
|
||||
Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
|
||||
Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, ListBase *lb, uiBlock *block, PanelType *pt, Panel *pa, bool *r_open)
|
||||
{
|
||||
Panel *palast, *panext;
|
||||
const char *drawname = CTX_IFACE_(pt->translation_context, pt->label);
|
||||
|
@ -275,9 +311,11 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
|
|||
pa->ofsy = 0;
|
||||
pa->sizex = 0;
|
||||
pa->sizey = 0;
|
||||
pa->blocksizex = 0;
|
||||
pa->blocksizey = 0;
|
||||
pa->runtime_flag |= PNL_NEW_ADDED;
|
||||
|
||||
BLI_addtail(&ar->panels, pa);
|
||||
BLI_addtail(lb, pa);
|
||||
|
||||
#ifdef UI_USE_PANELTAB
|
||||
BLI_strncpy(pa->tabname, tabname, sizeof(pa->tabname));
|
||||
|
@ -285,7 +323,7 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
|
|||
/* make new Panel tabbed? */
|
||||
if (hookname) {
|
||||
Panel *patab;
|
||||
for (patab = ar->panels.first; patab; patab = patab->next) {
|
||||
for (patab = lb->first; patab; patab = patab->next) {
|
||||
if ((patab->runtime_flag & PNL_ACTIVE) && patab->paneltab == NULL) {
|
||||
if (STREQLEN(hookname, patab->panelname, sizeof(patab->panelname))) {
|
||||
if (STREQLEN(tabname, patab->tabname, sizeof(patab->tabname))) {
|
||||
|
@ -308,6 +346,8 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
|
|||
/* Force update of panels' positions! */
|
||||
pa->sizex = 0;
|
||||
pa->sizey = 0;
|
||||
pa->blocksizex = 0;
|
||||
pa->blocksizey = 0;
|
||||
}
|
||||
|
||||
BLI_strncpy(pa->drawname, drawname, sizeof(pa->drawname));
|
||||
|
@ -315,14 +355,18 @@ Panel *UI_panel_begin(ScrArea *sa, ARegion *ar, uiBlock *block, PanelType *pt, P
|
|||
/* if a new panel is added, we insert it right after the panel
|
||||
* that was last added. this way new panels are inserted in the
|
||||
* right place between versions */
|
||||
for (palast = ar->panels.first; palast; palast = palast->next)
|
||||
if (palast->runtime_flag & PNL_LAST_ADDED)
|
||||
for (palast = lb->first; palast; palast = palast->next) {
|
||||
if (palast->runtime_flag & PNL_LAST_ADDED) {
|
||||
BLI_remlink(lb, pa);
|
||||
BLI_insertlinkafter(lb, palast, pa);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (newpanel) {
|
||||
pa->sortorder = (palast) ? palast->sortorder + 1 : 0;
|
||||
|
||||
for (panext = ar->panels.first; panext; panext = panext->next)
|
||||
for (panext = lb->first; panext; panext = panext->next)
|
||||
if (panext != pa && panext->sortorder >= pa->sortorder)
|
||||
panext->sortorder++;
|
||||
}
|
||||
|
@ -348,6 +392,19 @@ void UI_panel_end(uiBlock *block, int width, int height)
|
|||
{
|
||||
Panel *pa = block->panel;
|
||||
|
||||
/* Set panel size excluding children. */
|
||||
pa->blocksizex = width;
|
||||
pa->blocksizey = height;
|
||||
|
||||
/* Compute total panel size including children. */
|
||||
for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE) {
|
||||
width = max_ii(width, pachild->sizex);
|
||||
height += get_panel_real_size_y(pachild);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update total panel size. */
|
||||
if (pa->runtime_flag & PNL_NEW_ADDED) {
|
||||
pa->runtime_flag &= ~PNL_NEW_ADDED;
|
||||
pa->sizex = width;
|
||||
|
@ -372,15 +429,13 @@ void UI_panel_end(uiBlock *block, int width, int height)
|
|||
static void ui_offset_panel_block(uiBlock *block)
|
||||
{
|
||||
uiStyle *style = UI_style_get_dpi();
|
||||
uiBut *but;
|
||||
int ofsy;
|
||||
|
||||
/* compute bounds and offset */
|
||||
ui_block_bounds_calc(block);
|
||||
|
||||
ofsy = block->panel->sizey - style->panelspace;
|
||||
int ofsy = block->panel->sizey - style->panelspace;
|
||||
|
||||
for (but = block->buttons.first; but; but = but->next) {
|
||||
for (uiBut *but = block->buttons.first; but; but = but->next) {
|
||||
but->rect.ymin += ofsy;
|
||||
but->rect.ymax += ofsy;
|
||||
}
|
||||
|
@ -600,6 +655,8 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
|
|||
float color[4];
|
||||
const bool is_closed_x = (panel->flag & PNL_CLOSEDX) ? true : false;
|
||||
const bool is_closed_y = (panel->flag & PNL_CLOSEDY) ? true : false;
|
||||
const bool is_subpanel = (panel->type && panel->type->parent);
|
||||
const bool show_drag = !is_subpanel;
|
||||
|
||||
if (panel->paneltab) return;
|
||||
if (panel->type && (panel->type->flag & PNL_NO_HEADER)) return;
|
||||
|
@ -613,7 +670,7 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
|
|||
unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
{
|
||||
if (!is_subpanel) {
|
||||
float minx = rect->xmin;
|
||||
float maxx = is_closed_x ? (minx + PNL_HEADER / block->aspect) : rect->xmax;
|
||||
float y = headrect.ymax;
|
||||
|
@ -681,25 +738,28 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
|
|||
|
||||
/* horizontal title */
|
||||
if (is_closed_x == false) {
|
||||
unsigned int col;
|
||||
ui_draw_aligned_panel_header(style, block, &headrect, 'h');
|
||||
Gwn_VertFormat *format = immVertexFormat();
|
||||
pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
|
||||
|
||||
/* itemrect smaller */
|
||||
itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
|
||||
itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
|
||||
itemrect.ymin = headrect.ymin;
|
||||
itemrect.ymax = headrect.ymax;
|
||||
if (show_drag) {
|
||||
unsigned int col;
|
||||
Gwn_VertFormat *format = immVertexFormat();
|
||||
pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 4, GWN_FETCH_FLOAT);
|
||||
|
||||
BLI_rctf_scale(&itemrect, 0.7f);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
ui_draw_panel_dragwidget(pos, col, &itemrect);
|
||||
immUnbindProgram();
|
||||
/* itemrect smaller */
|
||||
itemrect.xmax = headrect.xmax - 5.0f / block->aspect;
|
||||
itemrect.xmin = itemrect.xmax - BLI_rcti_size_y(&headrect);
|
||||
itemrect.ymin = headrect.ymin;
|
||||
itemrect.ymax = headrect.ymax;
|
||||
|
||||
/* Restore format for the following draws. */
|
||||
pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
BLI_rctf_scale(&itemrect, 0.7f);
|
||||
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
|
||||
ui_draw_panel_dragwidget(pos, col, &itemrect);
|
||||
immUnbindProgram();
|
||||
|
||||
/* Restore format for the following draws. */
|
||||
pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
|
||||
}
|
||||
}
|
||||
|
||||
/* if the panel is minimized vertically:
|
||||
|
@ -727,8 +787,12 @@ void ui_draw_aligned_panel(uiStyle *style, uiBlock *block, const rcti *rect, con
|
|||
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
|
||||
|
||||
/* panel backdrop */
|
||||
if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
|
||||
/* draw with background color */
|
||||
if (is_subpanel) {
|
||||
glEnable(GL_BLEND);
|
||||
immUniformThemeColor(TH_PANEL_SUB_BACK);
|
||||
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
|
||||
}
|
||||
else if (UI_GetThemeValue(TH_PANEL_SHOW_BACK)) {
|
||||
glEnable(GL_BLEND);
|
||||
immUniformThemeColor(TH_PANEL_BACK);
|
||||
immRectf(pos, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
|
||||
|
@ -786,6 +850,16 @@ static int get_panel_size_y(Panel *pa)
|
|||
return PNL_HEADER + pa->sizey;
|
||||
}
|
||||
|
||||
static int get_panel_real_size_y(Panel *pa)
|
||||
{
|
||||
int sizey = (pa->flag & PNL_CLOSED) ? 0 : pa->sizey;
|
||||
|
||||
if (pa->type && (pa->type->flag & PNL_NO_HEADER))
|
||||
return sizey;
|
||||
|
||||
return PNL_HEADER + sizey;
|
||||
}
|
||||
|
||||
/* this function is needed because uiBlock and Panel itself don't
|
||||
* change sizey or location when closed */
|
||||
static int get_panel_real_ofsy(Panel *pa)
|
||||
|
@ -858,6 +932,24 @@ static int compare_panel(const void *a1, const void *a2)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void align_sub_panels(Panel *pa)
|
||||
{
|
||||
/* Position sub panels. */
|
||||
int ofsy = get_panel_real_ofsy(pa) + pa->sizey - pa->blocksizey;
|
||||
|
||||
for (Panel *pachild = pa->children.first; pachild; pachild = pachild->next) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE) {
|
||||
pachild->ofsx = pa->ofsx;
|
||||
pachild->ofsy = ofsy - get_panel_size_y(pachild);
|
||||
ofsy -= get_panel_real_size_y(pachild);
|
||||
|
||||
if (pachild->children.first) {
|
||||
align_sub_panels(pachild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* this doesnt draw */
|
||||
/* returns 1 when it did something */
|
||||
static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bool drag)
|
||||
|
@ -949,10 +1041,17 @@ static bool uiAlignPanelStep(ScrArea *sa, ARegion *ar, const float fac, const bo
|
|||
}
|
||||
}
|
||||
|
||||
/* copy locations to tabs */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next)
|
||||
if (pa->paneltab && (pa->runtime_flag & PNL_ACTIVE))
|
||||
ui_panel_copy_offset(pa, pa->paneltab);
|
||||
/* set locations for tabbed and sub panels */
|
||||
for (pa = ar->panels.first; pa; pa = pa->next) {
|
||||
if (pa->runtime_flag & PNL_ACTIVE) {
|
||||
if (pa->paneltab) {
|
||||
ui_panel_copy_offset(pa, pa->paneltab);
|
||||
}
|
||||
if (pa->children.first) {
|
||||
align_sub_panels(pa);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free panelsort array */
|
||||
for (ps = panelsort, a = 0; a < tot; a++, ps++) {
|
||||
|
@ -1022,20 +1121,27 @@ static void ui_do_animate(const bContext *C, Panel *panel)
|
|||
}
|
||||
}
|
||||
|
||||
void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
|
||||
static void panel_list_clear_active(ListBase *lb)
|
||||
{
|
||||
Panel *pa;
|
||||
|
||||
/* 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) {
|
||||
if (pa->runtime_flag & PNL_ACTIVE)
|
||||
for (Panel *pa = lb->first; pa; pa = pa->next) {
|
||||
if (pa->runtime_flag & PNL_ACTIVE) {
|
||||
pa->runtime_flag = PNL_WAS_ACTIVE;
|
||||
else
|
||||
}
|
||||
else {
|
||||
pa->runtime_flag = 0;
|
||||
}
|
||||
|
||||
panel_list_clear_active(&pa->children);
|
||||
}
|
||||
}
|
||||
|
||||
void UI_panels_begin(const bContext *UNUSED(C), ARegion *ar)
|
||||
{
|
||||
panel_list_clear_active(&ar->panels);
|
||||
}
|
||||
|
||||
/* only draws blocks with panels */
|
||||
void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y)
|
||||
{
|
||||
|
@ -1074,8 +1180,7 @@ void UI_panels_end(const bContext *C, ARegion *ar, int *x, int *y)
|
|||
}
|
||||
|
||||
/* re-align, possibly with animation */
|
||||
if (panels_re_align(sa, ar, &pa)) {
|
||||
/* XXX code never gets here... PNL_ANIM_ALIGN flag is never set */
|
||||
if (panels_need_realign(sa, ar, &pa)) {
|
||||
if (pa)
|
||||
panel_activate_state(C, pa, PANEL_STATE_ANIMATION);
|
||||
else
|
||||
|
@ -1102,14 +1207,16 @@ void UI_panels_draw(const bContext *C, ARegion *ar)
|
|||
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
|
||||
/* draw panels, selected on top */
|
||||
for (block = ar->uiblocks.first; block; block = block->next) {
|
||||
/* Draw panels, selected on top. Also in reverse order, because
|
||||
* UI blocks are added in reverse order and we need child panels
|
||||
* to draw on top. */
|
||||
for (block = ar->uiblocks.last; block; block = block->prev) {
|
||||
if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
|
||||
UI_block_draw(C, block);
|
||||
}
|
||||
}
|
||||
|
||||
for (block = ar->uiblocks.first; block; block = block->next) {
|
||||
for (block = ar->uiblocks.last; block; block = block->prev) {
|
||||
if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
|
||||
UI_block_draw(C, block);
|
||||
}
|
||||
|
@ -1371,6 +1478,8 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
|
|||
#else
|
||||
const bool show_pin = UI_panel_category_is_visible(ar);
|
||||
#endif
|
||||
const bool is_subpanel = (block->panel->type && block->panel->type->parent);
|
||||
const bool show_drag = !is_subpanel;
|
||||
|
||||
int align = panel_aligned(sa, ar), button = 0;
|
||||
|
||||
|
@ -1465,7 +1574,7 @@ static void ui_handle_panel_header(const bContext *C, uiBlock *block, int mx, in
|
|||
else
|
||||
ED_region_tag_redraw(ar);
|
||||
}
|
||||
else if (BLI_rctf_isect_x(&rect_drag, mx)) {
|
||||
else if (show_drag && BLI_rctf_isect_x(&rect_drag, mx)) {
|
||||
panel_activate_state(C, block->panel, PANEL_STATE_DRAG);
|
||||
}
|
||||
else if (show_pin && BLI_rctf_isect_x(&rect_pin, mx)) {
|
||||
|
|
|
@ -254,6 +254,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
|
|||
cp = ts->panelcolors.header; break;
|
||||
case TH_PANEL_BACK:
|
||||
cp = ts->panelcolors.back; break;
|
||||
case TH_PANEL_SUB_BACK:
|
||||
cp = ts->panelcolors.sub_back; break;
|
||||
case TH_PANEL_SHOW_HEADER:
|
||||
cp = &setting;
|
||||
setting = ts->panelcolors.show_header;
|
||||
|
@ -821,6 +823,7 @@ static void ui_theme_init_new_do(ThemeSpace *ts)
|
|||
ts->panelcolors.show_header = false;
|
||||
rgba_char_args_set(ts->panelcolors.back, 114, 114, 114, 128);
|
||||
rgba_char_args_set(ts->panelcolors.header, 0, 0, 0, 25);
|
||||
rgba_char_args_set(ts->panelcolors.sub_back, 0, 0, 0, 25);
|
||||
|
||||
rgba_char_args_set(ts->button, 145, 145, 145, 245);
|
||||
rgba_char_args_set(ts->button_title, 0, 0, 0, 255);
|
||||
|
@ -3022,6 +3025,16 @@ void init_userdef_do_versions(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (!USER_VERSION_ATLEAST(280, 17)) {
|
||||
for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
|
||||
ThemeSpace *ts;
|
||||
|
||||
for (ts = UI_THEMESPACE_START(btheme); ts != UI_THEMESPACE_END(btheme); ts++) {
|
||||
rgba_char_args_set(ts->panelcolors.sub_back, 0, 0, 0, 25);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Include next version bump.
|
||||
*/
|
||||
|
|
|
@ -1806,6 +1806,84 @@ BLI_INLINE bool streq_array_any(const char *s, const char *arr[])
|
|||
return false;
|
||||
}
|
||||
|
||||
static void ed_panel_draw(const bContext *C,
|
||||
ScrArea *sa,
|
||||
ARegion *ar,
|
||||
ListBase *lb,
|
||||
PanelType *pt,
|
||||
Panel *panel,
|
||||
int w,
|
||||
int em,
|
||||
bool vertical)
|
||||
{
|
||||
uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
/* draw panel */
|
||||
uiBlock *block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
|
||||
|
||||
bool open;
|
||||
panel = UI_panel_begin(sa, ar, lb, block, pt, panel, &open);
|
||||
|
||||
/* bad fixed values */
|
||||
int triangle = (int)(UI_UNIT_Y * 1.1f);
|
||||
int xco, yco, h = 0;
|
||||
|
||||
if (pt->draw_header && !(pt->flag & PNL_NO_HEADER) && (open || vertical)) {
|
||||
/* for enabled buttons */
|
||||
panel->layout = UI_block_layout(
|
||||
block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
|
||||
triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
|
||||
|
||||
pt->draw_header(C, panel);
|
||||
|
||||
UI_block_layout_resolve(block, &xco, &yco);
|
||||
panel->labelofs = xco - triangle;
|
||||
panel->layout = NULL;
|
||||
}
|
||||
else {
|
||||
panel->labelofs = 0;
|
||||
}
|
||||
|
||||
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 = UI_block_layout(
|
||||
block, UI_LAYOUT_VERTICAL, panelContext,
|
||||
style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
|
||||
|
||||
pt->draw(C, panel);
|
||||
|
||||
UI_block_layout_resolve(block, &xco, &yco);
|
||||
panel->layout = NULL;
|
||||
|
||||
if (yco != 0) {
|
||||
h = -yco + 2 * style->panelspace;
|
||||
}
|
||||
}
|
||||
|
||||
UI_block_end(C, block);
|
||||
|
||||
/* Draw child panels. */
|
||||
if (open) {
|
||||
for (LinkData *link = pt->children.first; link; link = link->next) {
|
||||
PanelType *child_pt = link->data;
|
||||
Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt);
|
||||
|
||||
if (child_pt->draw && (!child_pt->poll || child_pt->poll(C, child_pt))) {
|
||||
ed_panel_draw(C, sa, ar, &panel->children, child_pt, child_panel, w, em, vertical);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UI_panel_end(block, w, h);
|
||||
}
|
||||
|
||||
/**
|
||||
* \param contexts: A NULL terminated array of context strings to match against.
|
||||
* Matching against any of these strings will draw the panel.
|
||||
|
@ -1815,13 +1893,10 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
|
|||
{
|
||||
const WorkSpace *workspace = CTX_wm_workspace(C);
|
||||
ScrArea *sa = CTX_wm_area(C);
|
||||
uiStyle *style = UI_style_get_dpi();
|
||||
uiBlock *block;
|
||||
PanelType *pt;
|
||||
Panel *panel;
|
||||
View2D *v2d = &ar->v2d;
|
||||
View2DScrollers *scrollers;
|
||||
int x, y, xco, yco, w, em, triangle;
|
||||
int x, y, w, em;
|
||||
bool is_context_new = 0;
|
||||
int scroll;
|
||||
|
||||
|
@ -1859,6 +1934,11 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
|
|||
|
||||
/* collect panels to draw */
|
||||
for (pt = ar->type->paneltypes.last; pt; pt = pt->prev) {
|
||||
/* Only draw top level panels. */
|
||||
if (pt->parent) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* verify context */
|
||||
if (contexts && pt->context[0] && !streq_array_any(pt->context, contexts)) {
|
||||
continue;
|
||||
|
@ -1920,9 +2000,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
|
|||
|
||||
BLI_SMALLSTACK_ITER_BEGIN(pt_stack, pt)
|
||||
{
|
||||
bool open;
|
||||
|
||||
panel = UI_panel_find_by_type(ar, pt);
|
||||
Panel *panel = UI_panel_find_by_type(&ar->panels, pt);
|
||||
|
||||
if (use_category_tabs && pt->category[0] && !STREQ(category, pt->category)) {
|
||||
if ((panel == NULL) || ((panel->flag & PNL_PIN) == 0)) {
|
||||
|
@ -1930,56 +2008,7 @@ void ED_region_panels(const bContext *C, ARegion *ar, const char *contexts[], in
|
|||
}
|
||||
}
|
||||
|
||||
/* draw panel */
|
||||
block = UI_block_begin(C, ar, pt->idname, UI_EMBOSS);
|
||||
panel = UI_panel_begin(sa, ar, block, pt, panel, &open);
|
||||
|
||||
/* 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 = UI_block_layout(
|
||||
block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER,
|
||||
triangle, (UI_UNIT_Y * 1.1f) + style->panelspace, UI_UNIT_Y, 1, 0, style);
|
||||
|
||||
pt->draw_header(C, panel);
|
||||
|
||||
UI_block_layout_resolve(block, &xco, &yco);
|
||||
panel->labelofs = xco - triangle;
|
||||
panel->layout = NULL;
|
||||
}
|
||||
else {
|
||||
panel->labelofs = 0;
|
||||
}
|
||||
|
||||
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 = UI_block_layout(
|
||||
block, UI_LAYOUT_VERTICAL, panelContext,
|
||||
style->panelspace, 0, w - 2 * style->panelspace, em, 0, style);
|
||||
|
||||
pt->draw(C, panel);
|
||||
|
||||
UI_block_layout_resolve(block, &xco, &yco);
|
||||
panel->layout = NULL;
|
||||
|
||||
yco -= 2 * style->panelspace;
|
||||
UI_panel_end(block, w, -yco);
|
||||
}
|
||||
else {
|
||||
yco = 0;
|
||||
UI_panel_end(block, w, 0);
|
||||
}
|
||||
|
||||
UI_block_end(C, block);
|
||||
ed_panel_draw(C, sa, ar, &ar->panels, pt, panel, w, em, vertical);
|
||||
}
|
||||
BLI_SMALLSTACK_ITER_END;
|
||||
|
||||
|
|
|
@ -121,7 +121,9 @@ 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 */
|
||||
int ofsx, ofsy, sizex, sizey;
|
||||
int ofsx, ofsy; /* offset within the region */
|
||||
int sizex, sizey; /* panel size including children */
|
||||
int blocksizex, blocksizey; /* panel size excluding children */
|
||||
short labelofs, pad;
|
||||
short flag, runtime_flag;
|
||||
short control;
|
||||
|
@ -129,6 +131,7 @@ typedef struct Panel { /* the part from uiBlock that needs saved in file */
|
|||
int sortorder; /* panels are aligned according to increasing sortorder */
|
||||
struct Panel *paneltab; /* this panel is tabbed in *paneltab */
|
||||
void *activedata; /* runtime for panel manipulation */
|
||||
ListBase children; /* sub panels */
|
||||
} Panel;
|
||||
|
||||
|
||||
|
|
|
@ -150,9 +150,9 @@ typedef struct uiWidgetStateColors {
|
|||
typedef struct uiPanelColors {
|
||||
char header[4];
|
||||
char back[4];
|
||||
char sub_back[4];
|
||||
short show_header;
|
||||
short show_back;
|
||||
int pad;
|
||||
} uiPanelColors;
|
||||
|
||||
typedef struct uiGradientColors {
|
||||
|
|
|
@ -179,6 +179,12 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
|
|||
RNA_struct_free_extension(type, &pt->ext);
|
||||
RNA_struct_free(&BLENDER_RNA, type);
|
||||
|
||||
if (pt->parent) {
|
||||
LinkData *link = BLI_findptr(&pt->parent->children, pt, offsetof(LinkData, data));
|
||||
BLI_freelinkN(&pt->parent->children, link);
|
||||
}
|
||||
|
||||
BLI_freelistN(&pt->children);
|
||||
BLI_freelinkN(&art->paneltypes, pt);
|
||||
|
||||
/* update while blender is running */
|
||||
|
@ -190,7 +196,7 @@ static StructRNA *rna_Panel_register(
|
|||
StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
|
||||
{
|
||||
ARegionType *art;
|
||||
PanelType *pt, dummypt = {NULL};
|
||||
PanelType *pt, *parent = NULL, dummypt = {NULL};
|
||||
Panel dummypanel = {NULL};
|
||||
PointerRNA dummyptr;
|
||||
int have_function[3];
|
||||
|
@ -229,6 +235,10 @@ static StructRNA *rna_Panel_register(
|
|||
BLI_freelinkN(&art->paneltypes, pt);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dummypt.parent_id[0] && STREQ(pt->idname, dummypt.parent_id)) {
|
||||
parent = pt;
|
||||
}
|
||||
}
|
||||
if (!RNA_struct_available_or_report(reports, dummypt.idname)) {
|
||||
return NULL;
|
||||
|
@ -236,6 +246,11 @@ static StructRNA *rna_Panel_register(
|
|||
if (!RNA_struct_bl_idname_ok_or_report(reports, dummypt.idname, "_PT_")) {
|
||||
return NULL;
|
||||
}
|
||||
if (dummypt.parent_id[0] && !parent) {
|
||||
BKE_reportf(reports, RPT_ERROR, "Registering panel class: parent '%s' for '%s' not found",
|
||||
dummypt.parent_id, dummypt.idname);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* create a new panel type */
|
||||
pt = MEM_callocN(sizeof(PanelType), "python buttons panel");
|
||||
|
@ -267,6 +282,11 @@ static StructRNA *rna_Panel_register(
|
|||
else
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
|
||||
if (parent) {
|
||||
pt->parent = parent;
|
||||
BLI_addtail(&parent->children, BLI_genericNodeN(pt));
|
||||
}
|
||||
|
||||
{
|
||||
const char *owner_id = RNA_struct_state_owner_get();
|
||||
if (owner_id) {
|
||||
|
@ -1102,6 +1122,11 @@ static void rna_def_panel(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL | PROP_ENUM_FLAG);
|
||||
RNA_def_property_ui_text(prop, "Options", "Options for this panel type");
|
||||
|
||||
prop = RNA_def_property(srna, "bl_parent_id", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "type->parent_id");
|
||||
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
|
||||
RNA_def_property_ui_text(prop, "Parent ID Name", "If this is set, the panel becomes a subpanel");
|
||||
|
||||
prop = RNA_def_property(srna, "use_pin", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", PNL_PIN);
|
||||
RNA_def_property_ui_text(prop, "Pin", "");
|
||||
|
|
|
@ -902,6 +902,10 @@ static void rna_def_userdef_theme_ui_panel(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "back", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_ui_text(prop, "Background", "");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop = RNA_def_property(srna, "sub_back", PROP_FLOAT, PROP_COLOR_GAMMA);
|
||||
RNA_def_property_ui_text(prop, "Sub Background", "");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop = RNA_def_property(srna, "show_header", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Show Header", "");
|
||||
|
|
Loading…
Reference in New Issue