Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_outliner/outliner_draw.c
| Show First 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
| /* ****************************************************** */ | /* ****************************************************** */ | ||||
| /* Tree Size Functions */ | /* Tree Size Functions */ | ||||
| static void outliner_tree_dimensions_impl(SpaceOutliner *soops, | static void outliner_tree_dimensions_impl(SpaceOutliner *soops, | ||||
| ListBase *lb, | ListBase *lb, | ||||
| int *width, | int *width, | ||||
| int *height) | int *height) | ||||
| { | { | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| *width = MAX2(*width, te->xend); | *width = MAX2(*width, te->xend); | ||||
| if (height != NULL) { | if (height != NULL) { | ||||
| *height += UI_UNIT_Y; | *height += UI_UNIT_Y; | ||||
| } | } | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| if (TSELEM_OPEN(tselem, soops)) { | if (TSELEM_OPEN(tselem, soops)) { | ||||
| outliner_tree_dimensions_impl(soops, &te->subtree, width, height); | outliner_tree_dimensions_impl(soops, &te->subtree, width, height); | ||||
| ▲ Show 20 Lines • Show All 279 Lines • ▼ Show 20 Lines | static void outliner_collection_set_flag_recursive(Scene *scene, | ||||
| PointerRNA ptr; | PointerRNA ptr; | ||||
| outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr); | outliner_layer_or_collection_pointer_create(scene, layer_collection, collection, &ptr); | ||||
| RNA_property_boolean_set(&ptr, layer_or_collection_prop, value); | RNA_property_boolean_set(&ptr, layer_or_collection_prop, value); | ||||
| /* Set the same flag for the nested objects as well. */ | /* Set the same flag for the nested objects as well. */ | ||||
| if (base_or_object_prop) { | if (base_or_object_prop) { | ||||
| /* Note: We can't use BKE_collection_object_cache_get() | /* Note: We can't use BKE_collection_object_cache_get() | ||||
| * otherwise we would not take collection exclusion into account. */ | * otherwise we would not take collection exclusion into account. */ | ||||
| for (CollectionObject *cob = layer_collection->collection->gobject.first; cob; | LISTBASE_FOREACH (CollectionObject *, cob, &layer_collection->collection->gobject) { | ||||
| cob = cob->next) { | |||||
| outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr); | outliner_base_or_object_pointer_create(view_layer, collection, cob->ob, &ptr); | ||||
| RNA_property_boolean_set(&ptr, base_or_object_prop, value); | RNA_property_boolean_set(&ptr, base_or_object_prop, value); | ||||
| if (collection) { | if (collection) { | ||||
| DEG_id_tag_update(&cob->ob->id, ID_RECALC_COPY_ON_WRITE); | DEG_id_tag_update(&cob->ob->id, ID_RECALC_COPY_ON_WRITE); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* Keep going recursively. */ | /* Keep going recursively. */ | ||||
| ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); | ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); | ||||
| for (Link *link = lb->first; link; link = link->next) { | LISTBASE_FOREACH (Link *, link, lb) { | ||||
| LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; | LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; | ||||
| Collection *collection_iter = layer_collection ? | Collection *collection_iter = layer_collection ? | ||||
| (collection ? layer_collection_iter->collection : NULL) : | (collection ? layer_collection_iter->collection : NULL) : | ||||
| ((CollectionChild *)link)->collection; | ((CollectionChild *)link)->collection; | ||||
| outliner_collection_set_flag_recursive(scene, | outliner_collection_set_flag_recursive(scene, | ||||
| view_layer, | view_layer, | ||||
| layer_collection_iter, | layer_collection_iter, | ||||
| collection_iter, | collection_iter, | ||||
| ▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | else { | ||||
| * We expect it to be "invisible". */ | * We expect it to be "invisible". */ | ||||
| if (value == value_cmp) { | if (value == value_cmp) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| } | } | ||||
| /* Keep going recursively. */ | /* Keep going recursively. */ | ||||
| ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); | ListBase *lb = (layer_collection ? &layer_collection->layer_collections : &collection->children); | ||||
| for (Link *link = lb->first; link; link = link->next) { | LISTBASE_FOREACH (Link *, link, lb) { | ||||
| LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; | LayerCollection *layer_collection_iter = layer_collection ? (LayerCollection *)link : NULL; | ||||
| Collection *collection_iter = layer_collection ? | Collection *collection_iter = layer_collection ? | ||||
| (collection ? layer_collection_iter->collection : NULL) : | (collection ? layer_collection_iter->collection : NULL) : | ||||
| ((CollectionChild *)link)->collection; | ((CollectionChild *)link)->collection; | ||||
| if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) { | if (layer_collection_iter && layer_collection_iter->flag & LAYER_COLLECTION_EXCLUDE) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (!outliner_collection_is_isolated(scene, | if (!outliner_collection_is_isolated(scene, | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | void outliner_collection_isolate_flag(Scene *scene, | ||||
| /* Make this collection and its children collections the only "visible". */ | /* Make this collection and its children collections the only "visible". */ | ||||
| outliner_collection_set_flag_recursive( | outliner_collection_set_flag_recursive( | ||||
| scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide); | scene, view_layer, layer_collection, collection, layer_or_collection_prop, NULL, !is_hide); | ||||
| /* Make this collection direct parents also "visible". */ | /* Make this collection direct parents also "visible". */ | ||||
| if (layer_collection) { | if (layer_collection) { | ||||
| LayerCollection *lc_parent = layer_collection; | LayerCollection *lc_parent = layer_collection; | ||||
| for (LayerCollection *lc_iter = top_layer_collection->layer_collections.first; lc_iter; | LISTBASE_FOREACH (LayerCollection *, lc_iter, &top_layer_collection->layer_collections) { | ||||
| lc_iter = lc_iter->next) { | |||||
| if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { | if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { | ||||
| lc_parent = lc_iter; | lc_parent = lc_iter; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| while (lc_parent != layer_collection) { | while (lc_parent != layer_collection) { | ||||
| outliner_layer_or_collection_pointer_create( | outliner_layer_or_collection_pointer_create( | ||||
| scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr); | scene, lc_parent, collection ? lc_parent->collection : NULL, &ptr); | ||||
| RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide); | RNA_property_boolean_set(&ptr, layer_or_collection_prop, !is_hide); | ||||
| for (LayerCollection *lc_iter = lc_parent->layer_collections.first; lc_iter; | LISTBASE_FOREACH (LayerCollection *, lc_iter, &lc_parent->layer_collections) { | ||||
| lc_iter = lc_iter->next) { | |||||
| if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { | if (BKE_layer_collection_has_layer_collection(lc_iter, layer_collection)) { | ||||
| lc_parent = lc_iter; | lc_parent = lc_iter; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| ▲ Show 20 Lines • Show All 481 Lines • ▼ Show 20 Lines | if (soops->show_restrict_flags & SO_RESTRICT_SELECT) { | ||||
| restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; | restrict_offsets.select = (++restrict_column_offset) * UI_UNIT_X + V2D_SCROLL_WIDTH; | ||||
| } | } | ||||
| BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) == | BLI_assert((restrict_column_offset * UI_UNIT_X + V2D_SCROLL_WIDTH) == | ||||
| outliner_restrict_columns_width(soops)); | outliner_restrict_columns_width(soops)); | ||||
| /* Create buttons. */ | /* Create buttons. */ | ||||
| uiBut *bt; | uiBut *bt; | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| RestrictPropertiesActive props_active = props_active_parent; | RestrictPropertiesActive props_active = props_active_parent; | ||||
| if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | ||||
| if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) { | if (tselem->type == TSE_R_LAYER && (soops->outlinevis == SO_SCENES)) { | ||||
| if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { | if (soops->show_restrict_flags & SO_RESTRICT_RENDER) { | ||||
| /* View layer render toggle. */ | /* View layer render toggle. */ | ||||
| ViewLayer *layer = te->directdata; | ViewLayer *layer = te->directdata; | ||||
| ▲ Show 20 Lines • Show All 580 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void outliner_draw_userbuts(uiBlock *block, | static void outliner_draw_userbuts(uiBlock *block, | ||||
| ARegion *region, | ARegion *region, | ||||
| SpaceOutliner *soops, | SpaceOutliner *soops, | ||||
| ListBase *lb) | ListBase *lb) | ||||
| { | { | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | ||||
| if (tselem->type == 0) { | if (tselem->type == 0) { | ||||
| uiBut *bt; | uiBut *bt; | ||||
| ID *id = tselem->id; | ID *id = tselem->id; | ||||
| const char *tip = NULL; | const char *tip = NULL; | ||||
| int icon = ICON_NONE; | int icon = ICON_NONE; | ||||
| char buf[16] = ""; | char buf[16] = ""; | ||||
| ▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| static void outliner_draw_rnabuts( | static void outliner_draw_rnabuts( | ||||
| uiBlock *block, ARegion *region, SpaceOutliner *soops, int sizex, ListBase *lb) | uiBlock *block, ARegion *region, SpaceOutliner *soops, int sizex, ListBase *lb) | ||||
| { | { | ||||
| PointerRNA *ptr; | PointerRNA *ptr; | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | if (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && te->ys <= region->v2d.cur.ymax) { | ||||
| if (tselem->type == TSE_RNA_PROPERTY) { | if (tselem->type == TSE_RNA_PROPERTY) { | ||||
| ptr = &te->rnaptr; | ptr = &te->rnaptr; | ||||
| prop = te->directdata; | prop = te->directdata; | ||||
| if (!TSELEM_OPEN(tselem, soops)) { | if (!TSELEM_OPEN(tselem, soops)) { | ||||
| if (RNA_property_type(prop) == PROP_POINTER) { | if (RNA_property_type(prop) == PROP_POINTER) { | ||||
| ▲ Show 20 Lines • Show All 1,074 Lines • ▼ Show 20 Lines | static void outliner_draw_iconrow(bContext *C, | ||||
| int xmax, | int xmax, | ||||
| int *offsx, | int *offsx, | ||||
| int ys, | int ys, | ||||
| float alpha_fac, | float alpha_fac, | ||||
| MergedIconRow *merged) | MergedIconRow *merged) | ||||
| { | { | ||||
| eOLDrawState active = OL_DRAWSEL_NONE; | eOLDrawState active = OL_DRAWSEL_NONE; | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| /* object hierarchy always, further constrained on level */ | /* object hierarchy always, further constrained on level */ | ||||
| if (level < 1 || (tselem->type == 0 && te->idcode == ID_OB)) { | if (level < 1 || (tselem->type == 0 && te->idcode == ID_OB)) { | ||||
| /* active blocks get white circle */ | /* active blocks get white circle */ | ||||
| if (tselem->type == 0) { | if (tselem->type == 0) { | ||||
| if (te->idcode == ID_OB) { | if (te->idcode == ID_OB) { | ||||
| active = (tvc->obact == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE; | active = (tvc->obact == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE; | ||||
| ▲ Show 20 Lines • Show All 326 Lines • ▼ Show 20 Lines | static void outliner_draw_tree_element(bContext *C, | ||||
| /* store coord and continue, we need coordinates for elements outside view too */ | /* store coord and continue, we need coordinates for elements outside view too */ | ||||
| te->xs = startx; | te->xs = startx; | ||||
| te->ys = *starty; | te->ys = *starty; | ||||
| te->xend = startx + offsx; | te->xend = startx + offsx; | ||||
| if (TSELEM_OPEN(tselem, soops)) { | if (TSELEM_OPEN(tselem, soops)) { | ||||
| *starty -= UI_UNIT_Y; | *starty -= UI_UNIT_Y; | ||||
| for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) { | LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) { | ||||
| /* check if element needs to be drawn grayed out, but also gray out | /* check if element needs to be drawn grayed out, but also gray out | ||||
| * childs of a grayed out parent (pass on draw_grayed_out to childs) */ | * childs of a grayed out parent (pass on draw_grayed_out to childs) */ | ||||
| bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING); | bool draw_childs_grayed_out = draw_grayed_out || (ten->flag & TE_DRAGGING); | ||||
| outliner_draw_tree_element(C, | outliner_draw_tree_element(C, | ||||
| block, | block, | ||||
| fstyle, | fstyle, | ||||
| tvc, | tvc, | ||||
| region, | region, | ||||
| soops, | soops, | ||||
| ten, | ten, | ||||
| draw_childs_grayed_out, | draw_childs_grayed_out, | ||||
| startx + UI_UNIT_X, | startx + UI_UNIT_X, | ||||
| starty, | starty, | ||||
| restrict_column_width, | restrict_column_width, | ||||
| te_edit); | te_edit); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| for (TreeElement *ten = te->subtree.first; ten; ten = ten->next) { | LISTBASE_FOREACH (TreeElement *, ten, &te->subtree) { | ||||
| outliner_set_coord_tree_element(ten, startx, *starty); | outliner_set_coord_tree_element(ten, startx, *starty); | ||||
| } | } | ||||
| *starty -= UI_UNIT_Y; | *starty -= UI_UNIT_Y; | ||||
| } | } | ||||
| } | } | ||||
| static void outliner_draw_hierarchy_lines_recursive(uint pos, | static void outliner_draw_hierarchy_lines_recursive(uint pos, | ||||
| ▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | static void outliner_draw_hierarchy_lines(SpaceOutliner *soops, | ||||
| immUnbindProgram(); | immUnbindProgram(); | ||||
| } | } | ||||
| static void outliner_draw_struct_marks(ARegion *region, | static void outliner_draw_struct_marks(ARegion *region, | ||||
| SpaceOutliner *soops, | SpaceOutliner *soops, | ||||
| ListBase *lb, | ListBase *lb, | ||||
| int *starty) | int *starty) | ||||
| { | { | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| TreeStoreElem *tselem = TREESTORE(te); | TreeStoreElem *tselem = TREESTORE(te); | ||||
| /* selection status */ | /* selection status */ | ||||
| if (TSELEM_OPEN(tselem, soops)) { | if (TSELEM_OPEN(tselem, soops)) { | ||||
| if (tselem->type == TSE_RNA_STRUCT) { | if (tselem->type == TSE_RNA_STRUCT) { | ||||
| GPUVertFormat *format = immVertexFormat(); | GPUVertFormat *format = immVertexFormat(); | ||||
| uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); | uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT); | ||||
| immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); | immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR); | ||||
| Show All 32 Lines | static void outliner_draw_highlights_recursive(uint pos, | ||||
| const float col_highlight[4], | const float col_highlight[4], | ||||
| const float col_searchmatch[4], | const float col_searchmatch[4], | ||||
| int start_x, | int start_x, | ||||
| int *io_start_y) | int *io_start_y) | ||||
| { | { | ||||
| const bool is_searching = (SEARCHING_OUTLINER(soops) || | const bool is_searching = (SEARCHING_OUTLINER(soops) || | ||||
| (soops->outlinevis == SO_DATA_API && soops->search_string[0] != 0)); | (soops->outlinevis == SO_DATA_API && soops->search_string[0] != 0)); | ||||
| for (TreeElement *te = lb->first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| const TreeStoreElem *tselem = TREESTORE(te); | const TreeStoreElem *tselem = TREESTORE(te); | ||||
| const int start_y = *io_start_y; | const int start_y = *io_start_y; | ||||
| /* selection status */ | /* selection status */ | ||||
| if ((tselem->flag & TSE_ACTIVE) && (tselem->flag & TSE_SELECTED)) { | if ((tselem->flag & TSE_ACTIVE) && (tselem->flag & TSE_SELECTED)) { | ||||
| immUniformColor4fv(col_active); | immUniformColor4fv(col_active); | ||||
| immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y); | immRecti(pos, 0, start_y, (int)region->v2d.cur.xmax, start_y + UI_UNIT_Y); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | static void outliner_draw_tree(bContext *C, | ||||
| starty = (int)region->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET; | starty = (int)region->v2d.tot.ymax - UI_UNIT_Y / 2 - OL_Y_OFFSET; | ||||
| startx = UI_UNIT_X / 2 - (U.pixelsize + 1) / 2; | startx = UI_UNIT_X / 2 - (U.pixelsize + 1) / 2; | ||||
| outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty); | outliner_draw_hierarchy_lines(soops, &soops->tree, startx, &starty); | ||||
| // items themselves | // items themselves | ||||
| starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET; | starty = (int)region->v2d.tot.ymax - UI_UNIT_Y - OL_Y_OFFSET; | ||||
| startx = 0; | startx = 0; | ||||
| for (TreeElement *te = soops->tree.first; te; te = te->next) { | LISTBASE_FOREACH (TreeElement *, te, &soops->tree) { | ||||
| outliner_draw_tree_element(C, | outliner_draw_tree_element(C, | ||||
| block, | block, | ||||
| fstyle, | fstyle, | ||||
| tvc, | tvc, | ||||
| region, | region, | ||||
| soops, | soops, | ||||
| te, | te, | ||||
| (te->flag & TE_DRAGGING) != 0, | (te->flag & TE_DRAGGING) != 0, | ||||
| ▲ Show 20 Lines • Show All 160 Lines • Show Last 20 Lines | |||||