Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/workspace.c
| Show All 20 Lines | |||||
| /** \file blender/blenkernel/intern/workspace.c | /** \file blender/blenkernel/intern/workspace.c | ||||
| * \ingroup bke | * \ingroup bke | ||||
| */ | */ | ||||
| /* allow accessing private members of DNA_workspace_types.h */ | /* allow accessing private members of DNA_workspace_types.h */ | ||||
| #define DNA_PRIVATE_WORKSPACE_ALLOW | #define DNA_PRIVATE_WORKSPACE_ALLOW | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | |||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_string_utf8.h" | #include "BLI_string_utf8.h" | ||||
| #include "BLI_string_utils.h" | #include "BLI_string_utils.h" | ||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| ▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | static void *workspace_relation_get_data_matching_parent( | ||||
| if (relation != NULL) { | if (relation != NULL) { | ||||
| return relation->value; | return relation->value; | ||||
| } | } | ||||
| else { | else { | ||||
| return NULL; | return NULL; | ||||
| } | } | ||||
| } | } | ||||
| static void workspace_relation_remove_from_value( | |||||
| ListBase *relation_list, const void *value) | |||||
| { | |||||
| for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) { | |||||
| relation_next = relation->next; | |||||
| if (relation->value == value) { | |||||
| workspace_relation_remove(relation_list, relation); | |||||
| } | |||||
| } | |||||
| } | |||||
| /** | /** | ||||
| * Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple | * Checks if \a screen is already used within any workspace. A screen should never be assigned to multiple | ||||
| * WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks. | * WorkSpaceLayouts, but that should be ensured outside of the BKE_workspace module and without such checks. | ||||
| * Hence, this should only be used as assert check before assigining a screen to a workspace. | * Hence, this should only be used as assert check before assigining a screen to a workspace. | ||||
| */ | */ | ||||
| #ifndef NDEBUG | #ifndef NDEBUG | ||||
| static bool workspaces_is_screen_used | static bool workspaces_is_screen_used | ||||
| #else | #else | ||||
| Show All 23 Lines | |||||
| * The function that actually frees the workspace data (not workspace itself). It shouldn't be called | * The function that actually frees the workspace data (not workspace itself). It shouldn't be called | ||||
| * directly, instead #BKE_workspace_remove should be, which calls this through #BKE_libblock_free then. | * directly, instead #BKE_workspace_remove should be, which calls this through #BKE_libblock_free then. | ||||
| * | * | ||||
| * Should something like a bke_internal.h be added, this should go there! | * Should something like a bke_internal.h be added, this should go there! | ||||
| */ | */ | ||||
| void BKE_workspace_free(WorkSpace *workspace) | void BKE_workspace_free(WorkSpace *workspace) | ||||
| { | { | ||||
| BKE_workspace_relations_free(&workspace->hook_layout_relations); | BKE_workspace_relations_free(&workspace->hook_layout_relations); | ||||
| BKE_workspace_relations_free(&workspace->scene_viewlayer_relations); | BLI_freelistN(&workspace->scene_relations); | ||||
| BLI_freelistN(&workspace->owner_ids); | BLI_freelistN(&workspace->owner_ids); | ||||
| BLI_freelistN(&workspace->layouts); | BLI_freelistN(&workspace->layouts); | ||||
| for (bToolRef *tref = workspace->tools.first, *tref_next; tref; tref = tref_next) { | for (bToolRef *tref = workspace->tools.first, *tref_next; tref; tref = tref_next) { | ||||
| tref_next = tref->next; | tref_next = tref->next; | ||||
| if (tref->runtime) { | if (tref->runtime) { | ||||
| MEM_freeN(tref->runtime); | MEM_freeN(tref->runtime); | ||||
| ▲ Show 20 Lines • Show All 84 Lines • ▼ Show 20 Lines | void BKE_workspace_relations_free( | ||||
| ListBase *relation_list) | ListBase *relation_list) | ||||
| { | { | ||||
| for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) { | for (WorkSpaceDataRelation *relation = relation_list->first, *relation_next; relation; relation = relation_next) { | ||||
| relation_next = relation->next; | relation_next = relation->next; | ||||
| workspace_relation_remove(relation_list, relation); | workspace_relation_remove(relation_list, relation); | ||||
| } | } | ||||
| } | } | ||||
| void BKE_workspace_scene_relations_free_invalid( | |||||
| WorkSpace *workspace) | |||||
| { | |||||
| for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first, *relation_next; relation; relation = relation_next) { | |||||
| relation_next = relation->next; | |||||
| if (relation->scene == NULL) { | |||||
| BLI_freelinkN(&workspace->scene_relations, relation); | |||||
| } | |||||
| else if (!BLI_findstring(&relation->scene->view_layers, relation->view_layer, offsetof(ViewLayer, name))) { | |||||
| BLI_freelinkN(&workspace->scene_relations, relation); | |||||
| } | |||||
| } | |||||
| } | |||||
| /* -------------------------------------------------------------------- */ | /* -------------------------------------------------------------------- */ | ||||
| /* General Utils */ | /* General Utils */ | ||||
| void BKE_workspace_view_layer_remove_references( | void BKE_workspace_view_layer_rename( | ||||
| const Main *bmain, | |||||
| const Scene *scene, | |||||
| const char *old_name, | |||||
| const char *new_name) | |||||
| { | |||||
| for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { | |||||
| for (WorkSpaceSceneRelation *relation = workspace->scene_relations.first; relation; relation = relation->next) { | |||||
| if (relation->scene == scene && STREQ(relation->view_layer, old_name)) { | |||||
| STRNCPY(relation->view_layer, new_name); | |||||
| } | |||||
| } | |||||
| } | |||||
| } | |||||
| void BKE_workspace_view_layer_remove( | |||||
| const Main *bmain, | const Main *bmain, | ||||
| const ViewLayer *view_layer) | const ViewLayer *UNUSED(view_layer)) | ||||
| { | { | ||||
| for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { | for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) { | ||||
| workspace_relation_remove_from_value(&workspace->scene_viewlayer_relations, view_layer); | BKE_workspace_scene_relations_free_invalid(workspace); | ||||
| } | } | ||||
| } | } | ||||
| WorkSpaceLayout *BKE_workspace_layout_find( | WorkSpaceLayout *BKE_workspace_layout_find( | ||||
| const WorkSpace *workspace, const bScreen *screen) | const WorkSpace *workspace, const bScreen *screen) | ||||
| { | { | ||||
| WorkSpaceLayout *layout = workspace_layout_find_exec(workspace, screen); | WorkSpaceLayout *layout = workspace_layout_find_exec(workspace, screen); | ||||
| if (layout) { | if (layout) { | ||||
| ▲ Show 20 Lines • Show All 113 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene) | Base *BKE_workspace_active_base_get(const WorkSpace *workspace, const Scene *scene) | ||||
| { | { | ||||
| ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); | ViewLayer *view_layer = BKE_workspace_view_layer_get(workspace, scene); | ||||
| return view_layer->basact; | return view_layer->basact; | ||||
| } | } | ||||
| ViewLayer *BKE_workspace_view_layer_exists(const WorkSpace *workspace, const Scene *scene) | |||||
| { | |||||
| WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene)); | |||||
| return (relation) ? BLI_findstring(&scene->view_layers, relation->view_layer, offsetof(ViewLayer, name)) : NULL; | |||||
| } | |||||
| ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene) | ViewLayer *BKE_workspace_view_layer_get(const WorkSpace *workspace, const Scene *scene) | ||||
| { | { | ||||
| return workspace_relation_get_data_matching_parent(&workspace->scene_viewlayer_relations, scene); | ViewLayer *layer = BKE_workspace_view_layer_exists(workspace, scene); | ||||
| if (layer == NULL) { | |||||
| BKE_workspace_view_layer_set((WorkSpace*)workspace, scene->view_layers.first, (Scene *)scene); | |||||
| layer = scene->view_layers.first; | |||||
| } | |||||
| return layer; | |||||
| } | } | ||||
| void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene) | void BKE_workspace_view_layer_set(WorkSpace *workspace, ViewLayer *layer, Scene *scene) | ||||
| { | { | ||||
| workspace_relation_ensure_updated(&workspace->scene_viewlayer_relations, scene, layer); | WorkSpaceSceneRelation *relation = BLI_findptr(&workspace->scene_relations, scene, offsetof(WorkSpaceSceneRelation, scene)); | ||||
| if (relation == NULL) { | |||||
| relation = MEM_callocN(sizeof(*relation), __func__); | |||||
| } | |||||
| else { | |||||
| BLI_remlink(&workspace->scene_relations, relation); | |||||
| } | |||||
| /* (Re)insert at the head of the list, for faster lookups. */ | |||||
| relation->scene = scene; | |||||
| STRNCPY(relation->view_layer, layer->name); | |||||
| BLI_addhead(&workspace->scene_relations, relation); | |||||
| } | } | ||||
| ListBase *BKE_workspace_layouts_get(WorkSpace *workspace) | ListBase *BKE_workspace_layouts_get(WorkSpace *workspace) | ||||
| { | { | ||||
| return &workspace->layouts; | return &workspace->layouts; | ||||
| } | } | ||||
| const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout) | const char *BKE_workspace_layout_name_get(const WorkSpaceLayout *layout) | ||||
| { | { | ||||
| return layout->name; | return layout->name; | ||||
| } | } | ||||
| void BKE_workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name) | void BKE_workspace_layout_name_set(WorkSpace *workspace, WorkSpaceLayout *layout, const char *new_name) | ||||
| { | { | ||||
| workspace_layout_name_set(workspace, layout, new_name); | workspace_layout_name_set(workspace, layout, new_name); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 50 Lines • Show Last 20 Lines | |||||