Compare commits
73 Commits
cmbasnett/
...
property-s
Author | SHA1 | Date | |
---|---|---|---|
ef11238c74 | |||
1f768bbe41 | |||
ce6cf2b475 | |||
f957e09398 | |||
d58f361099 | |||
1b391f14fc | |||
b4b2185da0 | |||
8f548fd856 | |||
634bf8e4fc | |||
af146e7745 | |||
4b0a94661c | |||
8eda823dbc | |||
e40225577b | |||
d219d0efa1 | |||
cc1201dce3 | |||
1afdc92511 | |||
20ce4a77bd | |||
7d3d6ac085 | |||
304e9a0b9e | |||
31657ebbbe | |||
169ac2805e | |||
c914bff16d | |||
7758bb25e7 | |||
94272e8347 | |||
67d6d1363d | |||
b7d47e9892 | |||
6f5ca857fc | |||
71c6af4d59 | |||
2f68b79fa8 | |||
98c6349bca | |||
4c1095d33c | |||
847837c808 | |||
16bf1807a1 | |||
052baecc0d | |||
34c5245c32 | |||
42e5314727 | |||
7137e99ff3 | |||
f3e409c1bf | |||
92c201b493 | |||
7955c26f41 | |||
26450636cd | |||
f3b83271e6 | |||
136475dca3 | |||
544ac33b61 | |||
263e42a172 | |||
b7938c3768 | |||
be7a4f4a81 | |||
dbc9f1b0f3 | |||
f3caadec90 | |||
11b89dd56c | |||
5218fb969f | |||
411f425973 | |||
d4b9f41a56 | |||
66ac0448ef | |||
170a40c338 | |||
d2c00d1d7f | |||
cf99c25dbe | |||
c95d6de3b3 | |||
a33720329b | |||
9029c7be19 | |||
463c4ef39e | |||
c891ba0086 | |||
09e555142a | |||
4d5b6409ee | |||
712ccc2602 | |||
85fe4a18e8 | |||
8357b7fe46 | |||
13b283ca8e | |||
723f6e7f53 | |||
040931a9b2 | |||
a34c25046b | |||
e299727fba | |||
db76f34ed6 |
@@ -736,6 +736,8 @@ def km_property_editor(_params):
|
||||
{"properties": [("direction", 'PREV'), ], },),
|
||||
("screen.space_context_cycle", {"type": 'WHEELDOWNMOUSE', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("direction", 'NEXT'), ], },),
|
||||
("buttons.start_filter", {"type": 'F', "value": 'PRESS', "ctrl": True}, None),
|
||||
("buttons.clear_filter", {"type": 'F', "value": 'PRESS', "alt": True}, None),
|
||||
# Modifier panels
|
||||
("object.modifier_remove", {"type": 'X', "value": 'PRESS'}, {"properties": [("report", True)]}),
|
||||
("object.modifier_remove", {"type": 'DEL', "value": 'PRESS'}, {"properties": [("report", True)]}),
|
||||
|
@@ -44,6 +44,7 @@ class OBJECT_PT_constraints(ObjectConstraintPanel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_search = False
|
||||
|
||||
layout.operator_menu_enum("object.constraint_add", "type", text="Add Object Constraint")
|
||||
|
||||
@@ -58,6 +59,7 @@ class BONE_PT_constraints(BoneConstraintPanel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_search = False
|
||||
|
||||
layout.operator_menu_enum("pose.constraint_add", "type", text="Add Bone Constraint")
|
||||
|
||||
|
@@ -39,6 +39,7 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.use_property_search = False
|
||||
layout.operator_menu_enum("object.modifier_add", "type")
|
||||
layout.template_modifiers()
|
||||
|
||||
|
@@ -23,11 +23,20 @@ from bpy.types import Header, Panel
|
||||
class PROPERTIES_HT_header(Header):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
|
||||
def draw(self, _context):
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
view = context.space_data
|
||||
|
||||
layout.template_header()
|
||||
|
||||
layout.separator_spacer()
|
||||
layout.prop(view, "filter_text", icon='VIEWZOOM', text="")
|
||||
layout.separator_spacer()
|
||||
|
||||
row = layout.row()
|
||||
row.emboss = 'NONE'
|
||||
row.operator("buttons.toggle_pin", icon=('PINNED' if view.use_pin_id else 'UNPINNED'), text="")
|
||||
|
||||
|
||||
class PROPERTIES_PT_navigation_bar(Panel):
|
||||
bl_space_type = 'PROPERTIES'
|
||||
@@ -42,7 +51,11 @@ class PROPERTIES_PT_navigation_bar(Panel):
|
||||
|
||||
layout.scale_x = 1.4
|
||||
layout.scale_y = 1.4
|
||||
layout.prop_tabs_enum(view, "context", icon_only=True)
|
||||
if view.filter_text:
|
||||
layout.prop_tabs_enum(view, "context", data_highlight=view,
|
||||
property_highlight="context_search_filter_active", icon_only=True)
|
||||
else:
|
||||
layout.prop_tabs_enum(view, "context", icon_only=True)
|
||||
|
||||
|
||||
classes = (
|
||||
|
@@ -157,6 +157,11 @@ enum {
|
||||
UI_BLOCK_POPOVER_ONCE = 1 << 22,
|
||||
/** Always show keymaps, even for non-menus. */
|
||||
UI_BLOCK_SHOW_SHORTCUT_ALWAYS = 1 << 23,
|
||||
/** All items have been removed from the block by the search filter. */
|
||||
UI_BLOCK_FILTERED_EMPTY = 1 << 24,
|
||||
/** The block is only used during the layout process and will not be drawn,
|
||||
* for the case of a subpanel of a closed panel. */
|
||||
UI_BLOCK_SEARCH_ONLY = 1 << 25,
|
||||
};
|
||||
|
||||
/** #uiPopupBlockHandle.menuretval */
|
||||
@@ -671,6 +676,9 @@ enum {
|
||||
void UI_block_theme_style_set(uiBlock *block, char theme_style);
|
||||
char UI_block_emboss_get(uiBlock *block);
|
||||
void UI_block_emboss_set(uiBlock *block, char emboss);
|
||||
bool UI_block_has_search_filter(const uiBlock *block);
|
||||
bool UI_block_is_search_only(const uiBlock *block);
|
||||
void UI_block_set_search_only(uiBlock *block, bool search_only);
|
||||
|
||||
void UI_block_free(const struct bContext *C, uiBlock *block);
|
||||
void UI_blocklist_free(const struct bContext *C, struct ListBase *lb);
|
||||
@@ -1685,6 +1693,8 @@ void UI_panels_scale(struct ARegion *region, float new_width);
|
||||
void UI_panel_label_offset(struct uiBlock *block, int *r_x, int *r_y);
|
||||
int UI_panel_size_y(const struct Panel *panel);
|
||||
bool UI_panel_is_dragging(const struct Panel *panel);
|
||||
bool UI_panel_is_search_filtered(const struct Panel *panel);
|
||||
bool UI_panel_is_active(const struct Panel *panel);
|
||||
|
||||
bool UI_panel_category_is_visible(const struct ARegion *region);
|
||||
void UI_panel_category_add(struct ARegion *region, const char *name);
|
||||
@@ -1708,6 +1718,8 @@ struct PointerRNA *UI_region_panel_custom_data_under_cursor(const struct bContex
|
||||
const struct wmEvent *event);
|
||||
void UI_panel_custom_data_set(struct Panel *panel, struct PointerRNA *custom_data);
|
||||
|
||||
void UI_region_panels_remove_handlers(const struct bContext *C, struct ARegion *region);
|
||||
|
||||
/* Polyinstantiated panels for representing a list of data. */
|
||||
struct Panel *UI_panel_add_instanced(struct ScrArea *area,
|
||||
struct ARegion *region,
|
||||
@@ -1894,6 +1906,7 @@ void uiLayoutSetUnitsY(uiLayout *layout, float unit);
|
||||
void uiLayoutSetEmboss(uiLayout *layout, char emboss);
|
||||
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep);
|
||||
void uiLayoutSetPropDecorate(uiLayout *layout, bool is_sep);
|
||||
void uiLayoutSetPropSearch(uiLayout *layout, bool is_searchable);
|
||||
int uiLayoutGetLocalDir(const uiLayout *layout);
|
||||
|
||||
int uiLayoutGetOperatorContext(uiLayout *layout);
|
||||
@@ -1913,6 +1926,8 @@ float uiLayoutGetUnitsY(uiLayout *layout);
|
||||
int uiLayoutGetEmboss(uiLayout *layout);
|
||||
bool uiLayoutGetPropSep(uiLayout *layout);
|
||||
bool uiLayoutGetPropDecorate(uiLayout *layout);
|
||||
bool uiLayoutGetPropSearch(uiLayout *layout);
|
||||
void uiLayoutRootSetSearchOnly(uiLayout *layout, bool search_only);
|
||||
|
||||
/* layout specifiers */
|
||||
uiLayout *uiLayoutRow(uiLayout *layout, bool align);
|
||||
@@ -2358,7 +2373,10 @@ uiPropertySplitWrapper uiItemPropertySplitWrapperCreate(uiLayout *parent_layout)
|
||||
void uiItemL(uiLayout *layout, const char *name, int icon); /* label */
|
||||
void uiItemL_ex(
|
||||
uiLayout *layout, const char *name, int icon, const bool highlight, const bool redalert);
|
||||
uiLayout *uiItemL_respect_property_split(uiLayout *layout, const char *text, int icon);
|
||||
uiBut *uiItemL_respect_property_split(uiLayout *layout,
|
||||
const char *text,
|
||||
int icon,
|
||||
uiLayout **r_layout);
|
||||
/* label icon for dragging */
|
||||
void uiItemLDrag(uiLayout *layout, struct PointerRNA *ptr, const char *name, int icon);
|
||||
/* menu */
|
||||
@@ -2410,6 +2428,8 @@ void uiItemTabsEnumR_prop(uiLayout *layout,
|
||||
struct bContext *C,
|
||||
struct PointerRNA *ptr,
|
||||
PropertyRNA *prop,
|
||||
struct PointerRNA *ptr_highlight,
|
||||
PropertyRNA *prop_highlight,
|
||||
bool icon_only);
|
||||
|
||||
/* UI Operators */
|
||||
|
@@ -3425,12 +3425,20 @@ uiBlock *UI_block_begin(const bContext *C, ARegion *region, const char *name, ch
|
||||
|
||||
window = CTX_wm_window(C);
|
||||
scn = CTX_data_scene(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
|
||||
block = MEM_callocN(sizeof(uiBlock), "uiBlock");
|
||||
block->active = 1;
|
||||
block->emboss = emboss;
|
||||
block->evil_C = (void *)C; /* XXX */
|
||||
|
||||
/* Set the search filter for the properties editor. */
|
||||
if ((region && region->regiontype == RGN_TYPE_WINDOW) &&
|
||||
(area && area->spacetype == SPACE_PROPERTIES)) {
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
block->search_filter = sbuts->search_string;
|
||||
}
|
||||
|
||||
if (scn) {
|
||||
/* store display device name, don't lookup for transformations yet
|
||||
* block could be used for non-color displays where looking up for transformation
|
||||
@@ -3480,6 +3488,21 @@ void UI_block_theme_style_set(uiBlock *block, char theme_style)
|
||||
block->theme_style = theme_style;
|
||||
}
|
||||
|
||||
bool UI_block_has_search_filter(const uiBlock *block)
|
||||
{
|
||||
return block->search_filter != NULL && block->search_filter[0] != '\0';
|
||||
}
|
||||
|
||||
bool UI_block_is_search_only(const uiBlock *block)
|
||||
{
|
||||
return block->flag & UI_BLOCK_SEARCH_ONLY;
|
||||
}
|
||||
|
||||
void UI_block_set_search_only(uiBlock *block, bool search_only)
|
||||
{
|
||||
SET_FLAG_FROM_TEST(block->flag, search_only, UI_BLOCK_SEARCH_ONLY);
|
||||
}
|
||||
|
||||
static void ui_but_build_drawstr_float(uiBut *but, double value)
|
||||
{
|
||||
size_t slen = 0;
|
||||
|
@@ -79,6 +79,7 @@ enum {
|
||||
UI_HAS_ICON = (1 << 3),
|
||||
UI_HIDDEN = (1 << 4),
|
||||
UI_SELECT_DRAW = (1 << 5), /* Display selected, doesn't impact interaction. */
|
||||
UI_FILTERED = (1 << 12), /* Filtered by the search string, removed if in a layout. */
|
||||
/* warn: rest of uiBut->flag in UI_interface.h */
|
||||
};
|
||||
|
||||
@@ -273,6 +274,14 @@ struct uiBut {
|
||||
uiButPushedStateFunc pushed_state_func;
|
||||
void *pushed_state_arg;
|
||||
|
||||
/**
|
||||
* Used for property search, so that a button's label and decorator can be filtered and
|
||||
* unfiltered along with it. Due to the sometimes arbitrary nature of these values,
|
||||
* they aren't always filled.
|
||||
*/
|
||||
uiBut *label_but;
|
||||
uiBut *decorator_but;
|
||||
|
||||
/* pointer back */
|
||||
uiBlock *block;
|
||||
};
|
||||
@@ -393,7 +402,7 @@ struct uiBlock {
|
||||
|
||||
ListBase butstore; /* UI_butstore_* runtime function */
|
||||
|
||||
ListBase layouts;
|
||||
ListBase layouts; /* Note: Should be called layout_roots. */
|
||||
struct uiLayout *curlayout;
|
||||
|
||||
ListBase contexts;
|
||||
@@ -488,6 +497,8 @@ struct uiBlock {
|
||||
*/
|
||||
char display_device[64];
|
||||
|
||||
char *search_filter;
|
||||
|
||||
struct PieMenuData pie_data;
|
||||
};
|
||||
|
||||
@@ -777,6 +788,7 @@ extern void ui_draw_aligned_panel(struct uiStyle *style,
|
||||
const rcti *rect,
|
||||
const bool show_pin,
|
||||
const bool show_background);
|
||||
void ui_panel_set_search_filtered(struct Panel *panel, const bool value);
|
||||
|
||||
/* interface_draw.c */
|
||||
extern void ui_draw_dropshadow(
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -69,12 +69,14 @@
|
||||
#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
|
||||
#define PNL_NEW_ADDED 16
|
||||
#define PNL_FIRST 32
|
||||
#define PNL_LAST_ADDED (1 << 0)
|
||||
#define PNL_ACTIVE (1 << 1)
|
||||
#define PNL_WAS_ACTIVE (1 << 2)
|
||||
#define PNL_ANIM_ALIGN (1 << 3)
|
||||
#define PNL_NEW_ADDED (1 << 4)
|
||||
#define PNL_FIRST (1 << 5)
|
||||
#define PNL_SEARCH_FILTERED (1 << 6)
|
||||
#define PNL_WAS_SEARCH_FILTERED (1 << 7)
|
||||
|
||||
/* only show pin header button for pinned panels */
|
||||
#define USE_PIN_HIDDEN
|
||||
@@ -182,6 +184,18 @@ static bool panel_active_animation_changed(ListBase *lb, Panel **pa_animation, b
|
||||
}
|
||||
}
|
||||
|
||||
/* Detect search filter flag changes */
|
||||
if ((panel->runtime_flag & PNL_WAS_SEARCH_FILTERED) &&
|
||||
!(panel->runtime_flag & PNL_SEARCH_FILTERED)) {
|
||||
*pa_animation = panel;
|
||||
return false;
|
||||
}
|
||||
if (!(panel->runtime_flag & PNL_WAS_SEARCH_FILTERED) &&
|
||||
(panel->runtime_flag & PNL_SEARCH_FILTERED)) {
|
||||
*pa_animation = panel;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((panel->runtime_flag & PNL_ACTIVE) && !(panel->flag & PNL_CLOSED)) {
|
||||
if (panel_active_animation_changed(&panel->children, pa_animation, no_animation)) {
|
||||
return true;
|
||||
@@ -258,6 +272,7 @@ static Panel *UI_panel_add_instanced_ex(ScrArea *area,
|
||||
|
||||
panel->runtime.list_index = list_index;
|
||||
panel->runtime.custom_data_ptr = custom_data;
|
||||
panel->runtime_flag |= PNL_NEW_ADDED;
|
||||
|
||||
/* Add the panel's children too. Although they aren't instanced panels, we can still use this
|
||||
* function to create them, as UI_panel_begin does other things we don't need to do. */
|
||||
@@ -801,7 +816,7 @@ void UI_panel_end(
|
||||
|
||||
/* Compute total panel size including children. */
|
||||
LISTBASE_FOREACH (Panel *, pachild, &panel->children) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE && !UI_panel_is_search_filtered(pachild)) {
|
||||
width = max_ii(width, pachild->sizex);
|
||||
height += get_panel_real_size_y(pachild);
|
||||
}
|
||||
@@ -858,6 +873,45 @@ static void ui_offset_panel_block(uiBlock *block)
|
||||
block->rect.xmin = block->rect.ymin = 0.0;
|
||||
}
|
||||
|
||||
void ui_panel_set_search_filtered(struct Panel *panel, const bool value)
|
||||
{
|
||||
SET_FLAG_FROM_TEST(panel->runtime_flag, value, PNL_SEARCH_FILTERED);
|
||||
}
|
||||
|
||||
static void panel_is_search_filtered_recursive(const Panel *panel, bool *is_search_filtered)
|
||||
{
|
||||
*is_search_filtered = *is_search_filtered && (panel->runtime_flag & PNL_SEARCH_FILTERED);
|
||||
|
||||
/* If the panel is filtered (removed) we need to check that its children are too. */
|
||||
if (*is_search_filtered) {
|
||||
LISTBASE_FOREACH (const Panel *, child_panel, &panel->children) {
|
||||
panel_is_search_filtered_recursive(child_panel, is_search_filtered);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find whether a panel and all of its subpanels have been filtered by property search.
|
||||
*
|
||||
* \note We maintain a separate flag for active and search filtered. This prevents the
|
||||
* search filtering from being too invasive to other code and makes animation of search
|
||||
* filtered panels possible.
|
||||
*/
|
||||
bool UI_panel_is_search_filtered(const Panel *panel)
|
||||
{
|
||||
bool is_search_filtered = true;
|
||||
panel_is_search_filtered_recursive(panel, &is_search_filtered);
|
||||
return is_search_filtered;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a panel is currently active (displayed).
|
||||
*/
|
||||
bool UI_panel_is_active(const Panel *panel)
|
||||
{
|
||||
return panel->runtime_flag & PNL_ACTIVE;
|
||||
}
|
||||
|
||||
/**************************** drawing *******************************/
|
||||
|
||||
/* triangle 'icon' for panel header */
|
||||
@@ -1330,7 +1384,7 @@ static void align_sub_panels(Panel *panel)
|
||||
int ofsy = panel->ofsy + panel->sizey - panel->blocksizey;
|
||||
|
||||
LISTBASE_FOREACH (Panel *, pachild, &panel->children) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE) {
|
||||
if (pachild->runtime_flag & PNL_ACTIVE && !UI_panel_is_search_filtered(pachild)) {
|
||||
pachild->ofsx = panel->ofsx;
|
||||
pachild->ofsy = ofsy - get_panel_size_y(pachild);
|
||||
ofsy -= get_panel_real_size_y(pachild);
|
||||
@@ -1411,17 +1465,21 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
|
||||
ps->panel->ofsy = -get_panel_size_y(ps->panel);
|
||||
ps->panel->ofsx += ps->panel->runtime.region_ofsx;
|
||||
|
||||
/* Keep track of the last visible panel separately so we don't add space for filtered panels. */
|
||||
PanelSort *ps_last_visible = ps;
|
||||
for (a = 0; a < tot - 1; a++, ps++) {
|
||||
psnext = ps + 1;
|
||||
|
||||
if (align == BUT_VERTICAL) {
|
||||
bool use_box = ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX;
|
||||
bool use_box = ps_last_visible->panel->type &&
|
||||
ps_last_visible->panel->type->flag & PNL_DRAW_BOX;
|
||||
bool use_box_next = psnext->panel->type && psnext->panel->type->flag & PNL_DRAW_BOX;
|
||||
psnext->panel->ofsx = ps->panel->ofsx;
|
||||
psnext->panel->ofsy = get_panel_real_ofsy(ps->panel) - get_panel_size_y(psnext->panel);
|
||||
|
||||
/* Extra margin for box style panels. */
|
||||
ps->panel->ofsx += (use_box) ? UI_PANEL_BOX_STYLE_MARGIN : 0.0f;
|
||||
psnext->panel->ofsx = ps_last_visible->panel->ofsx;
|
||||
psnext->panel->ofsy = get_panel_real_ofsy(ps_last_visible->panel) -
|
||||
get_panel_size_y(psnext->panel);
|
||||
|
||||
/* Extra Y margin for box style panels. */
|
||||
if (use_box || use_box_next) {
|
||||
psnext->panel->ofsy -= UI_PANEL_BOX_STYLE_MARGIN;
|
||||
}
|
||||
@@ -1431,10 +1489,20 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
|
||||
psnext->panel->ofsy = ps->panel->ofsy + get_panel_size_y(ps->panel) -
|
||||
get_panel_size_y(psnext->panel);
|
||||
}
|
||||
|
||||
if (!UI_panel_is_search_filtered(psnext->panel)) {
|
||||
ps_last_visible = psnext;
|
||||
}
|
||||
}
|
||||
/* Extra margin for the last panel if it's a box-style panel. */
|
||||
if (panelsort[tot - 1].panel->type && panelsort[tot - 1].panel->type->flag & PNL_DRAW_BOX) {
|
||||
panelsort[tot - 1].panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN;
|
||||
|
||||
/* Extra X margin for box-style panels. */
|
||||
if (align == BUT_VERTICAL) {
|
||||
ps = panelsort;
|
||||
for (a = 0; a < tot; a++, ps++) {
|
||||
if (ps->panel->type && ps->panel->type->flag & PNL_DRAW_BOX) {
|
||||
ps->panel->ofsx += UI_PANEL_BOX_STYLE_MARGIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* we interpolate */
|
||||
@@ -1454,7 +1522,7 @@ static bool uiAlignPanelStep(ScrArea *area, ARegion *region, const float fac, co
|
||||
|
||||
/* set locations for tabbed and sub panels */
|
||||
LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
|
||||
if (panel->runtime_flag & PNL_ACTIVE) {
|
||||
if ((panel->runtime_flag & PNL_ACTIVE) && !UI_panel_is_search_filtered(panel)) {
|
||||
if (panel->children.first) {
|
||||
align_sub_panels(panel);
|
||||
}
|
||||
@@ -1478,7 +1546,7 @@ static void ui_panels_size(ScrArea *area, ARegion *region, int *r_x, int *r_y)
|
||||
|
||||
/* compute size taken up by panels, for setting in view2d */
|
||||
LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
|
||||
if (panel->runtime_flag & PNL_ACTIVE) {
|
||||
if (panel->runtime_flag & PNL_ACTIVE && !(panel->runtime_flag & PNL_SEARCH_FILTERED)) {
|
||||
int pa_sizex, pa_sizey;
|
||||
|
||||
if (align == BUT_VERTICAL) {
|
||||
@@ -1538,13 +1606,21 @@ static void ui_do_animate(bContext *C, Panel *panel)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set all panels as inactive, so that at the end of the panel layout building process
|
||||
* we know which ones are currently used. Also keep track of whether the panel was filtered
|
||||
* by property search so we can activate animation later if that changes.
|
||||
*/
|
||||
static void panel_list_clear_active(ListBase *lb)
|
||||
{
|
||||
/* set all panels as inactive, so that at the end we know
|
||||
* which ones were used */
|
||||
LISTBASE_FOREACH (Panel *, panel, lb) {
|
||||
if (panel->runtime_flag & PNL_ACTIVE) {
|
||||
bool was_search_filtered = panel->runtime_flag & PNL_SEARCH_FILTERED;
|
||||
panel->runtime_flag = PNL_WAS_ACTIVE;
|
||||
|
||||
if (was_search_filtered) {
|
||||
panel->runtime_flag |= PNL_WAS_SEARCH_FILTERED;
|
||||
}
|
||||
}
|
||||
else {
|
||||
panel->runtime_flag = 0;
|
||||
@@ -1600,23 +1676,27 @@ void UI_panels_end(const bContext *C, ARegion *region, int *r_x, int *r_y)
|
||||
ui_panels_size(area, region, r_x, r_y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw panels, selected on top, but not search filtered panels.
|
||||
*/
|
||||
void UI_panels_draw(const bContext *C, ARegion *region)
|
||||
{
|
||||
if (region->alignment != RGN_ALIGN_FLOAT) {
|
||||
UI_ThemeClearColor(TH_BACK);
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
/* Draw in reverse order, because UI blocks are added in reverse order
|
||||
* and we need child panels to draw on top. */
|
||||
LISTBASE_FOREACH_BACKWARD (uiBlock *, block, ®ion->uiblocks) {
|
||||
if (block->active && block->panel && !(block->panel->flag & PNL_SELECT)) {
|
||||
if (block->active && block->panel && !(block->panel->flag & PNL_SELECT) &&
|
||||
!UI_block_is_search_only(block) && !UI_panel_is_search_filtered(block->panel)) {
|
||||
UI_block_draw(C, block);
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH_BACKWARD (uiBlock *, block, ®ion->uiblocks) {
|
||||
if (block->active && block->panel && (block->panel->flag & PNL_SELECT)) {
|
||||
if (block->active && block->panel && (block->panel->flag & PNL_SELECT) &&
|
||||
!UI_block_is_search_only(block) && !UI_panel_is_search_filtered(block->panel)) {
|
||||
UI_block_draw(C, block);
|
||||
}
|
||||
}
|
||||
@@ -2801,6 +2881,13 @@ static void ui_handler_remove_panel(bContext *C, void *userdata)
|
||||
panel_activate_state(C, panel, PANEL_STATE_EXIT);
|
||||
}
|
||||
|
||||
void UI_region_panels_remove_handlers(const bContext *C, ARegion *region)
|
||||
{
|
||||
LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
|
||||
panel_activate_state(C, panel, PANEL_STATE_EXIT);
|
||||
}
|
||||
}
|
||||
|
||||
static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelState state)
|
||||
{
|
||||
uiHandlePanelData *data = panel->activedata;
|
||||
@@ -2828,7 +2915,7 @@ static void panel_activate_state(const bContext *C, Panel *panel, uiHandlePanelS
|
||||
}
|
||||
|
||||
if (state == PANEL_STATE_EXIT) {
|
||||
MEM_freeN(data);
|
||||
MEM_SAFE_FREE(data);
|
||||
panel->activedata = NULL;
|
||||
|
||||
WM_event_remove_ui_handler(
|
||||
|
@@ -860,7 +860,7 @@ static void template_ID(const bContext *C,
|
||||
|
||||
if (text) {
|
||||
/* Add label resepecting the separated layout property split state. */
|
||||
uiItemL_respect_property_split(layout, text, ICON_NONE);
|
||||
uiItemL_respect_property_split(layout, text, ICON_NONE, NULL);
|
||||
}
|
||||
|
||||
if (flag & UI_ID_BROWSE) {
|
||||
|
@@ -2365,7 +2365,8 @@ static void ed_panel_draw(const bContext *C,
|
||||
int w,
|
||||
int em,
|
||||
bool vertical,
|
||||
char *unique_panel_str)
|
||||
char *unique_panel_str,
|
||||
bool search_only)
|
||||
{
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
@@ -2378,6 +2379,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
strncat(block_name, unique_panel_str, LIST_PANEL_UNIQUE_STR_LEN);
|
||||
}
|
||||
uiBlock *block = UI_block_begin(C, region, block_name, UI_EMBOSS);
|
||||
UI_block_set_search_only(block, search_only);
|
||||
|
||||
bool open;
|
||||
panel = UI_panel_begin(area, region, lb, block, pt, panel, &open);
|
||||
@@ -2397,6 +2399,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
1,
|
||||
0,
|
||||
style);
|
||||
uiLayoutRootSetSearchOnly(panel->layout, search_only);
|
||||
|
||||
pt->draw_header_preset(C, panel);
|
||||
|
||||
@@ -2420,6 +2423,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
1,
|
||||
0,
|
||||
style);
|
||||
uiLayoutSetPropSearch(layout, false);
|
||||
panel->layout = uiLayoutRow(layout, false);
|
||||
}
|
||||
/* Regular case: Normal panel with fixed size buttons. */
|
||||
@@ -2427,6 +2431,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
panel->layout = UI_block_layout(
|
||||
block, UI_LAYOUT_HORIZONTAL, UI_LAYOUT_HEADER, labelx, labely, UI_UNIT_Y, 1, 0, style);
|
||||
}
|
||||
uiLayoutRootSetSearchOnly(panel->layout, search_only);
|
||||
|
||||
pt->draw_header(C, panel);
|
||||
|
||||
@@ -2438,7 +2443,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
panel->labelofs = 0;
|
||||
}
|
||||
|
||||
if (open) {
|
||||
if (open || UI_block_has_search_filter(block) || search_only) {
|
||||
short panelContext;
|
||||
|
||||
/* panel context can either be toolbar region or normal panels region */
|
||||
@@ -2462,6 +2467,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
em,
|
||||
0,
|
||||
style);
|
||||
uiLayoutRootSetSearchOnly(panel->layout, search_only || !open);
|
||||
|
||||
pt->draw(C, panel);
|
||||
|
||||
@@ -2476,7 +2482,7 @@ static void ed_panel_draw(const bContext *C,
|
||||
UI_block_end(C, block);
|
||||
|
||||
/* Draw child panels. */
|
||||
if (open) {
|
||||
if (open || UI_block_has_search_filter(block)) {
|
||||
LISTBASE_FOREACH (LinkData *, link, &pt->children) {
|
||||
PanelType *child_pt = link->data;
|
||||
Panel *child_panel = UI_panel_find_by_type(&panel->children, child_pt);
|
||||
@@ -2491,7 +2497,8 @@ static void ed_panel_draw(const bContext *C,
|
||||
w,
|
||||
em,
|
||||
vertical,
|
||||
unique_panel_str);
|
||||
unique_panel_str,
|
||||
!open);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2651,7 +2658,8 @@ void ED_region_panels_layout_ex(const bContext *C,
|
||||
(pt->flag & PNL_DRAW_BOX) ? w_box_panel : w,
|
||||
em,
|
||||
vertical,
|
||||
NULL);
|
||||
NULL,
|
||||
false);
|
||||
}
|
||||
|
||||
/* Draw "polyinstantaited" panels that don't have a 1 to 1 correspondence with their types. */
|
||||
@@ -2679,7 +2687,8 @@ void ED_region_panels_layout_ex(const bContext *C,
|
||||
(panel->type->flag & PNL_DRAW_BOX) ? w_box_panel : w,
|
||||
em,
|
||||
vertical,
|
||||
unique_panel_str);
|
||||
unique_panel_str,
|
||||
false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1101,27 +1101,18 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r
|
||||
|
||||
/************************* Drawing the Path ************************/
|
||||
|
||||
static void pin_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
|
||||
static bool buttons_panel_context_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
{
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
|
||||
if (sbuts->flag & SB_PIN_CONTEXT) {
|
||||
sbuts->pinid = buttons_context_id_path(C);
|
||||
}
|
||||
else {
|
||||
sbuts->pinid = NULL;
|
||||
}
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
return sbuts->mainb != BCONTEXT_TOOL;
|
||||
}
|
||||
|
||||
void buttons_context_draw(const bContext *C, uiLayout *layout)
|
||||
static void buttons_panel_context_draw(const bContext *C, Panel *panel)
|
||||
{
|
||||
uiLayout *layout = panel->layout;
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
ButsContextPath *path = sbuts->path;
|
||||
uiLayout *row;
|
||||
uiBlock *block;
|
||||
uiBut *but;
|
||||
PointerRNA *ptr;
|
||||
char namebuf[128], *name;
|
||||
int a, icon;
|
||||
@@ -1182,65 +1173,11 @@ void buttons_context_draw(const bContext *C, uiLayout *layout)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uiItemSpacer(row);
|
||||
|
||||
block = uiLayoutGetBlock(row);
|
||||
UI_block_emboss_set(block, UI_EMBOSS_NONE);
|
||||
but = uiDefIconButBitC(block,
|
||||
UI_BTYPE_ICON_TOGGLE,
|
||||
SB_PIN_CONTEXT,
|
||||
0,
|
||||
ICON_UNPINNED,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_X,
|
||||
UI_UNIT_Y,
|
||||
&sbuts->flag,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
TIP_("Follow context or keep fixed data-block displayed"));
|
||||
UI_but_flag_disable(but, UI_BUT_UNDO); /* skip undo on screen buttons */
|
||||
UI_but_func_set(but, pin_cb, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
static bool buttons_header_context_poll(const bContext *C, HeaderType *UNUSED(ht))
|
||||
#else
|
||||
static bool buttons_panel_context_poll(const bContext *C, PanelType *UNUSED(pt))
|
||||
#endif
|
||||
{
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
return (sbuts->mainb != BCONTEXT_TOOL);
|
||||
}
|
||||
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
static void buttons_header_context_draw(const bContext *C, Header *ptr)
|
||||
#else
|
||||
static void buttons_panel_context_draw(const bContext *C, Panel *ptr)
|
||||
#endif
|
||||
{
|
||||
buttons_context_draw(C, ptr->layout);
|
||||
}
|
||||
|
||||
void buttons_context_register(ARegionType *art)
|
||||
{
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
HeaderType *ht;
|
||||
|
||||
ht = MEM_callocN(sizeof(HeaderType), "spacetype buttons context header");
|
||||
strcpy(ht->idname, "BUTTONS_HT_context");
|
||||
ht->space_type = SPACE_PROPERTIES;
|
||||
ht->region_type = art->regionid;
|
||||
ht->poll = buttons_header_context_poll;
|
||||
ht->draw = buttons_header_context_draw;
|
||||
BLI_addtail(&art->headertypes, ht);
|
||||
#else
|
||||
PanelType *pt;
|
||||
|
||||
pt = MEM_callocN(sizeof(PanelType), "spacetype buttons panel context");
|
||||
PanelType *pt = MEM_callocN(sizeof(PanelType), "spacetype buttons panel context");
|
||||
strcpy(pt->idname, "BUTTONS_PT_context");
|
||||
strcpy(pt->label, N_("Context")); /* XXX C panels unavailable through RNA bpy.types! */
|
||||
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
|
||||
@@ -1248,7 +1185,6 @@ void buttons_context_register(ARegionType *art)
|
||||
pt->draw = buttons_panel_context_draw;
|
||||
pt->flag = PNL_NO_HEADER;
|
||||
BLI_addtail(&art->paneltypes, pt);
|
||||
#endif
|
||||
}
|
||||
|
||||
ID *buttons_context_id_path(const bContext *C)
|
||||
|
@@ -37,9 +37,6 @@ struct bNodeTree;
|
||||
struct uiLayout;
|
||||
struct wmOperatorType;
|
||||
|
||||
/* Display the context path in the header instead of the main window */
|
||||
#define USE_HEADER_CONTEXT_PATH
|
||||
|
||||
/* context data */
|
||||
|
||||
typedef struct ButsContextPath {
|
||||
@@ -83,7 +80,6 @@ void buttons_context_compute(const struct bContext *C, struct SpaceProperties *s
|
||||
int buttons_context(const struct bContext *C,
|
||||
const char *member,
|
||||
struct bContextDataResult *result);
|
||||
void buttons_context_draw(const struct bContext *C, struct uiLayout *layout);
|
||||
void buttons_context_register(struct ARegionType *art);
|
||||
struct ID *buttons_context_id_path(const struct bContext *C);
|
||||
|
||||
@@ -93,6 +89,9 @@ extern const char *buttons_context_dir[]; /* doc access */
|
||||
void buttons_texture_context_compute(const struct bContext *C, struct SpaceProperties *sbuts);
|
||||
|
||||
/* buttons_ops.c */
|
||||
void BUTTONS_OT_start_filter(struct wmOperatorType *ot);
|
||||
void BUTTONS_OT_clear_filter(struct wmOperatorType *ot);
|
||||
void BUTTONS_OT_toggle_pin(struct wmOperatorType *ot);
|
||||
void BUTTONS_OT_file_browse(struct wmOperatorType *ot);
|
||||
void BUTTONS_OT_directory_browse(struct wmOperatorType *ot);
|
||||
void BUTTONS_OT_context_menu(struct wmOperatorType *ot);
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_screen.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
#include "WM_types.h"
|
||||
@@ -52,6 +53,95 @@
|
||||
|
||||
#include "buttons_intern.h" /* own include */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Start / Clear Seach Filter Operators
|
||||
*
|
||||
* \note Almost a duplicate of the file browser operator #FILE_OT_start_filter.
|
||||
* \{ */
|
||||
|
||||
static int buttons_start_filter_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceProperties *space = CTX_wm_space_properties(C);
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_HEADER);
|
||||
|
||||
ARegion *region_ctx = CTX_wm_region(C);
|
||||
CTX_wm_region_set(C, region);
|
||||
UI_textbutton_activate_rna(C, region, space, "filter_text");
|
||||
CTX_wm_region_set(C, region_ctx);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void BUTTONS_OT_start_filter(struct wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Filter";
|
||||
ot->description = "Start entering filter text";
|
||||
ot->idname = "BUTTONS_OT_start_filter";
|
||||
|
||||
/* Callbacks. */
|
||||
ot->exec = buttons_start_filter_exec;
|
||||
ot->poll = ED_operator_buttons_active;
|
||||
}
|
||||
|
||||
static int buttons_clear_filter_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ScrArea *area = CTX_wm_area(C);
|
||||
SpaceProperties *space = CTX_wm_space_properties(C);
|
||||
|
||||
strcpy(space->search_string, "");
|
||||
|
||||
ED_area_tag_redraw(area);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void BUTTONS_OT_clear_filter(struct wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Clear Filter";
|
||||
ot->description = "Clear the search filter";
|
||||
ot->idname = "BUTTONS_OT_clear_filter";
|
||||
|
||||
/* Callbacks. */
|
||||
ot->exec = buttons_clear_filter_exec;
|
||||
ot->poll = ED_operator_buttons_active;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Pin ID Operator
|
||||
* \{ */
|
||||
|
||||
static int toggle_pin_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
|
||||
sbuts->pinid = (sbuts->flag & SB_PIN_CONTEXT) ? NULL : buttons_context_id_path(C);
|
||||
|
||||
sbuts->flag ^= SB_PIN_CONTEXT;
|
||||
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void BUTTONS_OT_toggle_pin(wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Toggle Pin ID";
|
||||
ot->description = "Keep the current data-block displayed";
|
||||
ot->idname = "BUTTONS_OT_toggle_pin";
|
||||
|
||||
/* Callbacks. */
|
||||
ot->exec = toggle_pin_exec;
|
||||
ot->poll = ED_operator_buttons_active;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Context Menu Operator
|
||||
* \{ */
|
||||
|
@@ -48,6 +48,7 @@
|
||||
#include "RNA_define.h"
|
||||
#include "RNA_enum_types.h"
|
||||
|
||||
#include "UI_interface.h"
|
||||
#include "UI_resources.h"
|
||||
|
||||
#include "buttons_intern.h" /* own include */
|
||||
@@ -123,6 +124,7 @@ static SpaceLink *buttons_duplicate(SpaceLink *sl)
|
||||
/* clear or remove stuff from old */
|
||||
sbutsn->path = NULL;
|
||||
sbutsn->texuser = NULL;
|
||||
strcpy(sbutsn->search_string, "");
|
||||
|
||||
return (SpaceLink *)sbutsn;
|
||||
}
|
||||
@@ -143,6 +145,7 @@ static void buttons_main_region_init(wmWindowManager *wm, ARegion *region)
|
||||
*
|
||||
* \return The total number of items in the array returned.
|
||||
*/
|
||||
/* HANS-TODO: Use short for this. */
|
||||
int ED_buttons_tabs_list(SpaceProperties *sbuts, int *context_tabs_array)
|
||||
{
|
||||
int length = 0;
|
||||
@@ -297,17 +300,86 @@ static void buttons_main_region_layout_properties(const bContext *C,
|
||||
C, region, ®ion->type->paneltypes, contexts, sbuts->mainb, vertical, NULL);
|
||||
}
|
||||
|
||||
static void buttons_main_region_layout(const bContext *C, ARegion *region)
|
||||
static void main_region_layout(const bContext *C, SpaceProperties *sbuts, ARegion *region)
|
||||
{
|
||||
/* draw entirely, view changes should be handled here */
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
|
||||
if (sbuts->mainb == BCONTEXT_TOOL) {
|
||||
ED_view3d_buttons_region_layout_ex(C, region, "Tool");
|
||||
}
|
||||
else {
|
||||
buttons_main_region_layout_properties(C, sbuts, region);
|
||||
}
|
||||
}
|
||||
|
||||
static void property_search_all_tabs(const bContext *C,
|
||||
SpaceProperties *sbuts,
|
||||
ARegion *main_region)
|
||||
{
|
||||
sbuts->context_search_filter_active = 0;
|
||||
|
||||
/* Duplicate space and region so we don't change any data for this space. */
|
||||
ScrArea *area_copy = MEM_dupallocN(CTX_wm_area(C));
|
||||
ARegion *region_copy = BKE_area_region_copy(CTX_wm_area(C)->type, main_region);
|
||||
BKE_area_region_panels_free(®ion_copy->panels);
|
||||
bContext *C_copy = CTX_copy(C);
|
||||
CTX_wm_area_set(C_copy, area_copy);
|
||||
CTX_wm_region_set(C_copy, region_copy);
|
||||
SpaceProperties *sbuts_copy = MEM_dupallocN(sbuts);
|
||||
|
||||
int context_tabs_array[32];
|
||||
int tabs_tot = ED_buttons_tabs_list(sbuts, context_tabs_array);
|
||||
|
||||
/* Loop through the tabs added to the properties editor. */
|
||||
for (int i = 0; i < tabs_tot; i++) {
|
||||
if (context_tabs_array[i] == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Run the layout with this tab set active. */
|
||||
sbuts_copy->mainb = sbuts->mainbo = sbuts_copy->mainbuser = context_tabs_array[i];
|
||||
|
||||
/* Run the layout for the actual region if the tab matches to avoid doing it again later on. */
|
||||
const bool use_actual_region = sbuts->mainb == sbuts_copy->mainb;
|
||||
if (use_actual_region) {
|
||||
main_region_layout(C, sbuts, main_region);
|
||||
}
|
||||
else {
|
||||
main_region_layout(C_copy, sbuts_copy, region_copy);
|
||||
}
|
||||
|
||||
/* Store whether this tab has any unfiltered panels left. */
|
||||
bool has_unfiltered_panel = false;
|
||||
LISTBASE_FOREACH (
|
||||
Panel *, panel, use_actual_region ? &main_region->panels : ®ion_copy->panels) {
|
||||
has_unfiltered_panel |= !UI_panel_is_search_filtered(panel) && UI_panel_is_active(panel);
|
||||
}
|
||||
if (has_unfiltered_panel) {
|
||||
sbuts->context_search_filter_active |= (1 << i);
|
||||
}
|
||||
|
||||
/* Free data created during the layout process. */
|
||||
UI_region_panels_remove_handlers(C_copy, region_copy);
|
||||
BKE_area_region_panels_free(®ion_copy->panels);
|
||||
UI_blocklist_free(C_copy, ®ion_copy->uiblocks);
|
||||
}
|
||||
|
||||
BKE_area_region_free(CTX_wm_area(C_copy)->type, region_copy);
|
||||
MEM_freeN(region_copy);
|
||||
MEM_freeN(sbuts_copy);
|
||||
MEM_freeN(area_copy);
|
||||
MEM_freeN(C_copy);
|
||||
}
|
||||
|
||||
static void buttons_main_region_layout(const bContext *C, ARegion *region)
|
||||
{
|
||||
/* draw entirely, view changes should be handled here */
|
||||
SpaceProperties *sbuts = CTX_wm_space_properties(C);
|
||||
|
||||
if (sbuts->search_string != NULL && sbuts->search_string[0] != '\0') {
|
||||
property_search_all_tabs(C, sbuts, region);
|
||||
}
|
||||
else {
|
||||
main_region_layout(C, sbuts, region);
|
||||
}
|
||||
|
||||
sbuts->mainbo = sbuts->mainb;
|
||||
}
|
||||
@@ -330,6 +402,9 @@ static void buttons_main_region_listener(wmWindow *UNUSED(win),
|
||||
|
||||
static void buttons_operatortypes(void)
|
||||
{
|
||||
WM_operatortype_append(BUTTONS_OT_start_filter);
|
||||
WM_operatortype_append(BUTTONS_OT_clear_filter);
|
||||
WM_operatortype_append(BUTTONS_OT_toggle_pin);
|
||||
WM_operatortype_append(BUTTONS_OT_context_menu);
|
||||
WM_operatortype_append(BUTTONS_OT_file_browse);
|
||||
WM_operatortype_append(BUTTONS_OT_directory_browse);
|
||||
@@ -343,14 +418,6 @@ static void buttons_keymap(struct wmKeyConfig *keyconf)
|
||||
/* add handlers, stuff you only do once or on area/region changes */
|
||||
static void buttons_header_region_init(wmWindowManager *UNUSED(wm), ARegion *region)
|
||||
{
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
/* Reinsert context buttons header-type at the end of the list so it's drawn last. */
|
||||
HeaderType *context_ht = BLI_findstring(
|
||||
®ion->type->headertypes, "BUTTONS_HT_context", offsetof(HeaderType, idname));
|
||||
BLI_remlink(®ion->type->headertypes, context_ht);
|
||||
BLI_addtail(®ion->type->headertypes, context_ht);
|
||||
#endif
|
||||
|
||||
ED_region_header_init(region);
|
||||
}
|
||||
|
||||
@@ -390,10 +457,6 @@ static void buttons_header_region_message_subscribe(const bContext *UNUSED(C),
|
||||
if (sbuts->mainb == BCONTEXT_TOOL) {
|
||||
WM_msg_subscribe_rna_anon_prop(mbus, WorkSpace, tools, &msg_sub_value_region_tag_redraw);
|
||||
}
|
||||
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
WM_msg_subscribe_rna_anon_prop(mbus, SpaceProperties, context, &msg_sub_value_region_tag_redraw);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void buttons_navigation_bar_region_init(wmWindowManager *wm, ARegion *region)
|
||||
@@ -727,9 +790,7 @@ void ED_spacetype_buttons(void)
|
||||
art->draw = ED_region_panels_draw;
|
||||
art->listener = buttons_main_region_listener;
|
||||
art->keymapflag = ED_KEYMAP_UI | ED_KEYMAP_FRAMES;
|
||||
#ifndef USE_HEADER_CONTEXT_PATH
|
||||
buttons_context_register(art);
|
||||
#endif
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* Register the panel types from modifiers. The actual panels are built per modifier rather than
|
||||
@@ -765,9 +826,6 @@ void ED_spacetype_buttons(void)
|
||||
art->init = buttons_header_region_init;
|
||||
art->draw = buttons_header_region_draw;
|
||||
art->message_subscribe = buttons_header_region_message_subscribe;
|
||||
#ifdef USE_HEADER_CONTEXT_PATH
|
||||
buttons_context_register(art);
|
||||
#endif
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: navigation bar */
|
||||
|
@@ -423,7 +423,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
col = uiLayoutColumn(layout, true);
|
||||
/* keyframe itself */
|
||||
{
|
||||
uiItemL_respect_property_split(col, IFACE_("Key Frame"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Key Frame"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
@@ -441,7 +441,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
-1,
|
||||
NULL);
|
||||
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
@@ -468,7 +468,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
uiItemL_respect_property_split(col, IFACE_("Left Handle Type"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Left Handle Type"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_MENU,
|
||||
B_REDR,
|
||||
@@ -487,7 +487,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
"Type of left handle");
|
||||
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
|
||||
|
||||
uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
@@ -506,7 +506,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
NULL);
|
||||
UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
|
||||
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
@@ -532,7 +532,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
/* NOTE: special update callbacks are needed on the coords here due to T39911 */
|
||||
|
||||
col = uiLayoutColumn(layout, true);
|
||||
uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Right Handle Type"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_MENU,
|
||||
B_REDR,
|
||||
@@ -551,7 +551,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
"Type of right handle");
|
||||
UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
|
||||
|
||||
uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Frame"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
@@ -570,7 +570,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *panel)
|
||||
NULL);
|
||||
UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
|
||||
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE);
|
||||
uiItemL_respect_property_split(col, IFACE_("Value"), ICON_NONE, NULL);
|
||||
but = uiDefButR(block,
|
||||
UI_BTYPE_NUM,
|
||||
B_REDR,
|
||||
|
@@ -147,9 +147,12 @@ typedef struct SpaceProperties {
|
||||
|
||||
/** Context tabs. */
|
||||
short mainb, mainbo, mainbuser;
|
||||
/** Bitfield flag (in the same order as the tabs) for whether each tab has properties
|
||||
* that match the search filter. Only valid when #search_string is set. */
|
||||
int context_search_filter_active;
|
||||
/** Preview is signal to refresh. */
|
||||
short preview;
|
||||
char _pad[5];
|
||||
char _pad[1];
|
||||
char flag;
|
||||
|
||||
/** Runtime. */
|
||||
@@ -158,6 +161,9 @@ typedef struct SpaceProperties {
|
||||
int pathflag, dataicon;
|
||||
ID *pinid;
|
||||
|
||||
/** For filtering properties displayed in the space. */
|
||||
char search_string[64];
|
||||
|
||||
void *texuser;
|
||||
} SpaceProperties;
|
||||
|
||||
|
@@ -4469,6 +4469,22 @@ static void rna_def_space_properties(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "use_pin_id", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", SB_PIN_CONTEXT);
|
||||
RNA_def_property_ui_text(prop, "Pin ID", "Use the pinned context");
|
||||
|
||||
/* Property search. */
|
||||
prop = RNA_def_property(srna, "context_search_filter_active", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, buttons_context_items);
|
||||
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
|
||||
RNA_def_property_enum_funcs(
|
||||
prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf");
|
||||
RNA_def_property_ui_text(prop, "", "");
|
||||
RNA_def_property_update(
|
||||
prop, NC_SPACE | ND_SPACE_PROPERTIES, "rna_SpaceProperties_context_update");
|
||||
|
||||
prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_sdna(prop, NULL, "search_string");
|
||||
RNA_def_property_ui_text(prop, "Display Filter", "Live search filtering string");
|
||||
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
|
||||
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL);
|
||||
}
|
||||
|
||||
static void rna_def_space_image(BlenderRNA *brna)
|
||||
|
@@ -1151,6 +1151,16 @@ static void rna_UILayout_property_decorate_set(PointerRNA *ptr, bool value)
|
||||
uiLayoutSetPropDecorate(ptr->data, value);
|
||||
}
|
||||
|
||||
static bool rna_UILayout_property_search_get(PointerRNA *ptr)
|
||||
{
|
||||
return uiLayoutGetPropSearch(ptr->data);
|
||||
}
|
||||
|
||||
static void rna_UILayout_property_search_set(PointerRNA *ptr, bool value)
|
||||
{
|
||||
uiLayoutSetPropSearch(ptr->data, value);
|
||||
}
|
||||
|
||||
#else /* RNA_RUNTIME */
|
||||
|
||||
static void rna_def_ui_layout(BlenderRNA *brna)
|
||||
@@ -1267,6 +1277,12 @@ static void rna_def_ui_layout(BlenderRNA *brna)
|
||||
prop = RNA_def_property(srna, "use_property_decorate", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_UILayout_property_decorate_get", "rna_UILayout_property_decorate_set");
|
||||
|
||||
prop = RNA_def_property(srna, "use_property_search", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(
|
||||
prop, "rna_UILayout_property_search_get", "rna_UILayout_property_search_set");
|
||||
RNA_def_property_ui_text(
|
||||
prop, "Use Property Search", "Whether to use the region's property search if available");
|
||||
}
|
||||
|
||||
static void rna_def_panel(BlenderRNA *brna)
|
||||
|
@@ -216,8 +216,13 @@ static void rna_uiItemMenuEnumR(uiLayout *layout,
|
||||
uiItemMenuEnumR_prop(layout, ptr, prop, name, icon);
|
||||
}
|
||||
|
||||
static void rna_uiItemTabsEnumR(
|
||||
uiLayout *layout, bContext *C, struct PointerRNA *ptr, const char *propname, bool icon_only)
|
||||
static void rna_uiItemTabsEnumR(uiLayout *layout,
|
||||
bContext *C,
|
||||
struct PointerRNA *ptr,
|
||||
const char *propname,
|
||||
struct PointerRNA *ptr_highlight,
|
||||
const char *propname_highlight,
|
||||
bool icon_only)
|
||||
{
|
||||
PropertyRNA *prop = RNA_struct_find_property(ptr, propname);
|
||||
|
||||
@@ -230,7 +235,31 @@ static void rna_uiItemTabsEnumR(
|
||||
return;
|
||||
}
|
||||
|
||||
uiItemTabsEnumR_prop(layout, C, ptr, prop, icon_only);
|
||||
/* Get the highlight property used to gray out some of the tabs. */
|
||||
PropertyRNA *prop_highlight = NULL;
|
||||
if (!RNA_pointer_is_null(ptr_highlight)) {
|
||||
prop_highlight = RNA_struct_find_property(ptr_highlight, propname_highlight);
|
||||
if (!prop_highlight) {
|
||||
RNA_warning("property not found: %s.%s",
|
||||
RNA_struct_identifier(ptr_highlight->type),
|
||||
propname_highlight);
|
||||
return;
|
||||
}
|
||||
if (RNA_property_type(prop_highlight) != PROP_ENUM) {
|
||||
RNA_warning("property is not an enum: %s.%s",
|
||||
RNA_struct_identifier(ptr_highlight->type),
|
||||
propname_highlight);
|
||||
return;
|
||||
}
|
||||
if (!(RNA_property_flag(prop_highlight) & PROP_ENUM_FLAG)) {
|
||||
RNA_warning("property must be a bitfield enum: %s.%s",
|
||||
RNA_struct_identifier(ptr_highlight->type),
|
||||
propname_highlight);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
uiItemTabsEnumR_prop(layout, C, ptr, prop, ptr_highlight, prop_highlight, icon_only);
|
||||
}
|
||||
|
||||
static void rna_uiItemEnumR_string(uiLayout *layout,
|
||||
@@ -920,6 +949,11 @@ void RNA_api_ui_layout(StructRNA *srna)
|
||||
func = RNA_def_function(srna, "prop_tabs_enum", "rna_uiItemTabsEnumR");
|
||||
RNA_def_function_flag(func, FUNC_USE_CONTEXT);
|
||||
api_ui_item_rna_common(func);
|
||||
parm = RNA_def_pointer(
|
||||
func, "data_highlight", "AnyType", "", "Data from which to take highlight property");
|
||||
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_RNAPTR);
|
||||
parm = RNA_def_string(
|
||||
func, "property_highlight", NULL, 0, "", "Identifier of highlight property in data");
|
||||
RNA_def_boolean(func, "icon_only", false, "", "Draw only icons in tabs, no text");
|
||||
|
||||
func = RNA_def_function(srna, "prop_enum", "rna_uiItemEnumR_string");
|
||||
|
Reference in New Issue
Block a user