Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_outliner/outliner_draw.c
| Show First 20 Lines • Show All 1,769 Lines • ▼ Show 20 Lines | LISTBASE_FOREACH (TreeElement *, te, lb) { | ||||
| } | } | ||||
| if (TSELEM_OPEN(tselem, space_outliner)) { | if (TSELEM_OPEN(tselem, space_outliner)) { | ||||
| outliner_draw_userbuts(block, region, space_outliner, &te->subtree); | outliner_draw_userbuts(block, region, space_outliner, &te->subtree); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static bool outliner_draw_overrides_buts(uiBlock *block, | |||||
| ARegion *region, | |||||
| SpaceOutliner *space_outliner, | |||||
| ListBase *lb, | |||||
| const bool is_open) | |||||
| { | |||||
| bool any_item_has_warnings = false; | |||||
| LISTBASE_FOREACH (TreeElement *, te, lb) { | |||||
| bool item_has_warnings = false; | |||||
| const bool do_draw = (te->ys + 2 * UI_UNIT_Y >= region->v2d.cur.ymin && | |||||
| te->ys <= region->v2d.cur.ymax); | |||||
Severin: Meh, we keep repeating this same check, should be moved into a function. But I can do that… | |||||
Done Inline ActionsYes, would rather not add even more unrelated cleanup/refactor in this patch, it already has too many. ;) mont29: Yes, would rather not add even more unrelated cleanup/refactor in this patch, it already has… | |||||
| int but_flag = UI_BUT_DRAG_LOCK; | |||||
| const char *tip = NULL; | |||||
| TreeStoreElem *tselem = TREESTORE(te); | |||||
| switch (tselem->type) { | |||||
| case TSE_LIBRARY_OVERRIDE_BASE: { | |||||
| ID *id = tselem->id; | |||||
| if (ID_IS_OVERRIDE_LIBRARY_REAL(id) && ID_REAL_USERS(id) == 0) { | |||||
| item_has_warnings = true; | |||||
| if (do_draw) { | |||||
| tip = TIP_("This override data-block is unused"); | |||||
| } | |||||
| } | |||||
| else if (id->flag & LIB_LIB_OVERRIDE_RESYNC_LEFTOVER) { | |||||
| item_has_warnings = true; | |||||
| if (do_draw) { | |||||
| tip = TIP_( | |||||
| "This override data-block is not needed anymore, but was detected as user-edited"); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| case TSE_LIBRARY_OVERRIDE: { | |||||
| const bool is_rna_path_valid = (bool)(POINTER_AS_UINT(te->directdata)); | |||||
| if (!is_rna_path_valid) { | |||||
| item_has_warnings = true; | |||||
| if (do_draw) { | |||||
| tip = TIP_( | |||||
| "This override property does not exist in current data, it will be removed on " | |||||
| "next .blend file save"); | |||||
| } | |||||
| } | |||||
| break; | |||||
| } | |||||
| default: | |||||
| break; | |||||
| } | |||||
| const bool any_child_has_warnings = outliner_draw_overrides_buts( | |||||
| block, | |||||
| region, | |||||
| space_outliner, | |||||
| &te->subtree, | |||||
| is_open && TSELEM_OPEN(tselem, space_outliner)); | |||||
| if (do_draw && | |||||
| (item_has_warnings || (any_child_has_warnings && !TSELEM_OPEN(tselem, space_outliner)))) { | |||||
| if (tip == NULL) { | |||||
| tip = TIP_("Some sub-items require attention"); | |||||
| } | |||||
| uiBut *bt = uiDefIconBlockBut(block, | |||||
| NULL, | |||||
| NULL, | |||||
| 1, | |||||
| ICON_ERROR, | |||||
| (int)(region->v2d.cur.xmax - OL_TOG_USER_BUTS_STATUS), | |||||
| te->ys, | |||||
| UI_UNIT_X, | |||||
| UI_UNIT_Y, | |||||
| tip); | |||||
| UI_but_flag_enable(bt, but_flag); | |||||
| } | |||||
| any_item_has_warnings = any_item_has_warnings || item_has_warnings || any_child_has_warnings; | |||||
Done Inline ActionsWhy call this parent_has_warnings? This doesn't seem to check the parent. Maybe any_has_warnings or any_item_has_warnings? And maybe has_warnings should become item_has_warnings, to be clear that this only relates to the current item. Severin: Why call this `parent_has_warnings`? This doesn't seem to check the parent. Maybe… | |||||
| } | |||||
| return any_item_has_warnings; | |||||
| } | |||||
| static void outliner_draw_rnacols(ARegion *region, int sizex) | static void outliner_draw_rnacols(ARegion *region, int sizex) | ||||
| { | { | ||||
| View2D *v2d = ®ion->v2d; | View2D *v2d = ®ion->v2d; | ||||
| float miny = v2d->cur.ymin; | float miny = v2d->cur.ymin; | ||||
| if (miny < v2d->tot.ymin) { | if (miny < v2d->tot.ymin) { | ||||
| miny = v2d->tot.ymin; | miny = v2d->tot.ymin; | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 1,105 Lines • ▼ Show 20 Lines | if ((level < 1) || ((tselem->type == TSE_SOME_ID) && (te->idcode == ID_OB))) { | ||||
| else { | else { | ||||
| active = tree_element_active_state_get(tvc, te, tselem); | active = tree_element_active_state_get(tvc, te, tselem); | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| active = tree_element_type_active_state_get(C, tvc, te, tselem); | active = tree_element_type_active_state_get(C, tvc, te, tselem); | ||||
| } | } | ||||
| if (!ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION, TSE_R_LAYER, TSE_GP_LAYER)) { | if (!ELEM(tselem->type, | ||||
| TSE_ID_BASE, | |||||
| TSE_SOME_ID, | |||||
| TSE_LAYER_COLLECTION, | |||||
| TSE_R_LAYER, | |||||
| TSE_GP_LAYER, | |||||
| TSE_LIBRARY_OVERRIDE_BASE, | |||||
| TSE_LIBRARY_OVERRIDE, | |||||
| TSE_BONE, | |||||
| TSE_EBONE, | |||||
| TSE_POSE_CHANNEL, | |||||
| TSE_POSEGRP, | |||||
| TSE_DEFGROUP)) { | |||||
| outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1); | outliner_draw_iconrow_doit(block, te, fstyle, xmax, offsx, ys, alpha_fac, active, 1); | ||||
Not Done Inline ActionsI asked Nathan why only few types used the icon merging before. I don't see a reason myself. Severin: I asked Nathan why only few types used the icon merging before. I don't see a reason myself. | |||||
Not Done Inline Actions@Julian Eisel (Severin) I don't know either. Those types were always there from what I recall. natecraddock: @Severin I don't know either. Those types were always there from what I recall. | |||||
| } | } | ||||
| else { | else { | ||||
| const int index = tree_element_id_type_to_index(te); | const int index = tree_element_id_type_to_index(te); | ||||
| merged->num_elements[index]++; | merged->num_elements[index]++; | ||||
| if ((merged->tree_element[index] == NULL) || (active > merged->active[index])) { | if ((merged->tree_element[index] == NULL) || (active > merged->active[index])) { | ||||
| merged->tree_element[index] = te; | merged->tree_element[index] = te; | ||||
| } | } | ||||
| merged->active[index] = MAX2(active, merged->active[index]); | merged->active[index] = MAX2(active, merged->active[index]); | ||||
| ▲ Show 20 Lines • Show All 742 Lines • ▼ Show 20 Lines | void draw_outliner(const bContext *C) | ||||
| outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, space_outliner, region); /* Always. */ | outliner_build_tree(mainvar, tvc.scene, tvc.view_layer, space_outliner, region); /* Always. */ | ||||
| /* If global sync select is dirty, flag other outliners. */ | /* If global sync select is dirty, flag other outliners. */ | ||||
| if (ED_outliner_select_sync_is_dirty(C)) { | if (ED_outliner_select_sync_is_dirty(C)) { | ||||
| ED_outliner_select_sync_flag_outliners(C); | ED_outliner_select_sync_flag_outliners(C); | ||||
| } | } | ||||
| /* Sync selection state from view layer. */ | /* Sync selection state from view layer. */ | ||||
| if (!ELEM(space_outliner->outlinevis, SO_LIBRARIES, SO_DATA_API, SO_ID_ORPHANS) && | if (!ELEM(space_outliner->outlinevis, | ||||
| SO_LIBRARIES, | |||||
| SO_OVERRIDES_LIBRARY, | |||||
| SO_DATA_API, | |||||
| SO_ID_ORPHANS) && | |||||
| space_outliner->flag & SO_SYNC_SELECT) { | space_outliner->flag & SO_SYNC_SELECT) { | ||||
| outliner_sync_selection(C, space_outliner); | outliner_sync_selection(C, space_outliner); | ||||
| } | } | ||||
| /* Force display to pixel coords. */ | /* Force display to pixel coords. */ | ||||
| v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y); | v2d->flag |= (V2D_PIXELOFS_X | V2D_PIXELOFS_Y); | ||||
| /* Set matrix for 2D-view controls. */ | /* Set matrix for 2D-view controls. */ | ||||
| UI_view2d_view_ortho(v2d); | UI_view2d_view_ortho(v2d); | ||||
| Show All 30 Lines | if (space_outliner->outlinevis == SO_DATA_API) { | ||||
| UI_block_emboss_set(block, UI_EMBOSS); | UI_block_emboss_set(block, UI_EMBOSS); | ||||
| outliner_draw_rnabuts(block, region, space_outliner, buttons_start_x, &space_outliner->tree); | outliner_draw_rnabuts(block, region, space_outliner, buttons_start_x, &space_outliner->tree); | ||||
| UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); | UI_block_emboss_set(block, UI_EMBOSS_NONE_OR_STATUS); | ||||
| } | } | ||||
| else if (space_outliner->outlinevis == SO_ID_ORPHANS) { | else if (space_outliner->outlinevis == SO_ID_ORPHANS) { | ||||
| /* draw user toggle columns */ | /* draw user toggle columns */ | ||||
| outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree); | outliner_draw_userbuts(block, region, space_outliner, &space_outliner->tree); | ||||
| } | } | ||||
| else if (space_outliner->outlinevis == SO_OVERRIDES_LIBRARY) { | |||||
| /* Draw overrides status columns. */ | |||||
| outliner_draw_overrides_buts(block, region, space_outliner, &space_outliner->tree, true); | |||||
| } | |||||
| else if (restrict_column_width > 0.0f) { | else if (restrict_column_width > 0.0f) { | ||||
| /* draw restriction columns */ | /* draw restriction columns */ | ||||
| RestrictPropertiesActive props_active; | RestrictPropertiesActive props_active; | ||||
| memset(&props_active, 1, sizeof(RestrictPropertiesActive)); | memset(&props_active, 1, sizeof(RestrictPropertiesActive)); | ||||
| outliner_draw_restrictbuts(block, | outliner_draw_restrictbuts(block, | ||||
| tvc.scene, | tvc.scene, | ||||
| tvc.view_layer, | tvc.view_layer, | ||||
| region, | region, | ||||
| Show All 24 Lines | |||||
Meh, we keep repeating this same check, should be moved into a function. But I can do that after this patch is in.